mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°6043 - Booking: Add prerequisites in iTop core - CRUD extensibility (#520)
This commit is contained in:
111
sources/Service/TemporaryObjects/TemporaryObjectConfig.php
Normal file
111
sources/Service/TemporaryObjects/TemporaryObjectConfig.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Service\TemporaryObjects;
|
||||
|
||||
use MetaModel;
|
||||
|
||||
class TemporaryObjectConfig
|
||||
{
|
||||
|
||||
private int $iGarbageInterval;
|
||||
private int $iConfigTemporaryLifetime;
|
||||
private bool $bConfigTemporaryForce;
|
||||
private int $iWatchdogInterval;
|
||||
private static ?TemporaryObjectConfig $oSingletonInstance = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
// Retrieve service configuration
|
||||
$oConfig = MetaModel::GetConfig();
|
||||
$this->iGarbageInterval = $oConfig->Get(TemporaryObjectHelper::CONFIG_GARBAGE_INTERVAL);
|
||||
$this->iConfigTemporaryLifetime = $oConfig->Get(TemporaryObjectHelper::CONFIG_TEMP_LIFETIME);
|
||||
$this->bConfigTemporaryForce = $oConfig->Get(TemporaryObjectHelper::CONFIG_FORCE);
|
||||
$this->iWatchdogInterval = $oConfig->Get(TemporaryObjectHelper::CONFIG_GARBAGE_INTERVAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* GetInstance.
|
||||
*
|
||||
* @return TemporaryObjectConfig
|
||||
*/
|
||||
public static function GetInstance(): TemporaryObjectConfig
|
||||
{
|
||||
if (is_null(self::$oSingletonInstance)) {
|
||||
self::$oSingletonInstance = new TemporaryObjectConfig();
|
||||
}
|
||||
|
||||
return self::$oSingletonInstance;
|
||||
}
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function GetGarbageInterval(): int
|
||||
{
|
||||
return $this->iGarbageInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iGarbageInterval
|
||||
*/
|
||||
public function SetGarbageInterval(int $iGarbageInterval): void
|
||||
{
|
||||
$this->iGarbageInterval = $iGarbageInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function GetConfigTemporaryLifetime(): int
|
||||
{
|
||||
return $this->iConfigTemporaryLifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iConfigTemporaryLifetime
|
||||
*/
|
||||
public function SetConfigTemporaryLifetime(int $iConfigTemporaryLifetime): void
|
||||
{
|
||||
$this->iConfigTemporaryLifetime = $iConfigTemporaryLifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function GetConfigTemporaryForce(): bool
|
||||
{
|
||||
return $this->bConfigTemporaryForce;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $bConfigTemporaryForce
|
||||
*/
|
||||
public function SetConfigTemporaryForce(bool $bConfigTemporaryForce): void
|
||||
{
|
||||
$this->bConfigTemporaryForce = $bConfigTemporaryForce;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function GetWatchdogInterval(): int
|
||||
{
|
||||
return $this->iWatchdogInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iWatchdogInterval
|
||||
*/
|
||||
public function SetWatchdogInterval(int $iWatchdogInterval): void
|
||||
{
|
||||
$this->iWatchdogInterval = $iWatchdogInterval;
|
||||
}
|
||||
|
||||
}
|
||||
45
sources/Service/TemporaryObjects/TemporaryObjectGC.php
Normal file
45
sources/Service/TemporaryObjects/TemporaryObjectGC.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Service\TemporaryObjects;
|
||||
|
||||
use iBackgroundProcess;
|
||||
|
||||
/**
|
||||
* TemporaryObjectGC.
|
||||
*
|
||||
* Background task to collect and garbage expired temporary objects..
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
class TemporaryObjectGC implements iBackgroundProcess
|
||||
{
|
||||
/** @var TemporaryObjectManager */
|
||||
private TemporaryObjectManager $oTemporaryObjectManager;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Retrieve service dependencies
|
||||
$this->oTemporaryObjectManager = TemporaryObjectManager::GetInstance();
|
||||
}
|
||||
|
||||
/** @inheritDoc * */
|
||||
public function GetPeriodicity()
|
||||
{
|
||||
return TemporaryObjectConfig::GetInstance()->GetWatchdogInterval();
|
||||
}
|
||||
|
||||
/** @inheritDoc * */
|
||||
public function Process($iUnixTimeLimit)
|
||||
{
|
||||
// Garbage temporary objects
|
||||
$this->oTemporaryObjectManager->GarbageExpiredTemporaryObjects();
|
||||
}
|
||||
}
|
||||
45
sources/Service/TemporaryObjects/TemporaryObjectHelper.php
Normal file
45
sources/Service/TemporaryObjects/TemporaryObjectHelper.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Service\TemporaryObjects;
|
||||
|
||||
/**
|
||||
* TemporaryObjectHelper.
|
||||
*
|
||||
* Helper with useful functions.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
class TemporaryObjectHelper
|
||||
{
|
||||
// Global configuration
|
||||
const CONFIG_FORCE = 'temporary_object.force_creation';
|
||||
const CONFIG_TEMP_LIFETIME = 'temporary_object.lifetime';
|
||||
const CONFIG_WATCHDOG_INTERVAL = 'temporary_object.watchdog_interval';
|
||||
const CONFIG_GARBAGE_INTERVAL = 'temporary_object.garbage_interval';
|
||||
|
||||
// Temporary descriptor operation
|
||||
const OPERATION_CREATE = 'create';
|
||||
const OPERATION_DELETE = 'delete';
|
||||
|
||||
/**
|
||||
* GetWatchDogJS.
|
||||
*
|
||||
* @param string $sTempId
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
static public function GetWatchDogJS(string $sTempId): string
|
||||
{
|
||||
$iWatchdogInterval = TemporaryObjectConfig::GetInstance()->GetWatchdogInterval();
|
||||
|
||||
return <<<JS
|
||||
window.setInterval(function() {
|
||||
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?route=temporary_object.watch_dog', {temp_id: '$sTempId'});
|
||||
}, $iWatchdogInterval * 1000)
|
||||
JS;
|
||||
}
|
||||
}
|
||||
400
sources/Service/TemporaryObjects/TemporaryObjectManager.php
Normal file
400
sources/Service/TemporaryObjects/TemporaryObjectManager.php
Normal file
@@ -0,0 +1,400 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Service\TemporaryObjects;
|
||||
|
||||
use DateTime;
|
||||
use DBObject;
|
||||
use Exception;
|
||||
use ExceptionLog;
|
||||
use IssueLog;
|
||||
use LogChannels;
|
||||
use MetaModel;
|
||||
use TemporaryObjectDescriptor;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* TemporaryObjectManager.
|
||||
*
|
||||
* Manager class to perform global temporary objects tasks.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
class TemporaryObjectManager
|
||||
{
|
||||
/** @var TemporaryObjectManager|null Singleton */
|
||||
static private ?TemporaryObjectManager $oSingletonInstance = null;
|
||||
|
||||
/** @var TemporaryObjectRepository $oTemporaryObjectRepository */
|
||||
private TemporaryObjectRepository $oTemporaryObjectRepository;
|
||||
|
||||
/**
|
||||
* GetInstance.
|
||||
*
|
||||
* @return TemporaryObjectManager
|
||||
*/
|
||||
public static function GetInstance(): TemporaryObjectManager
|
||||
{
|
||||
if (is_null(self::$oSingletonInstance)) {
|
||||
self::$oSingletonInstance = new TemporaryObjectManager();
|
||||
}
|
||||
|
||||
return self::$oSingletonInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
// Retrieve service dependencies
|
||||
$this->oTemporaryObjectRepository = TemporaryObjectRepository::GetInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* CreateTemporaryObject.
|
||||
*
|
||||
* @param string $sTempId Temporary id context for the temporary object
|
||||
* @param string $sObjectClass Temporary object class
|
||||
* @param string $sObjectKey Temporary object key
|
||||
* @param string $sOperation temporary operation on file TemporaryObjectHelper::OPERATION_CREATE or TemporaryObjectHelper::OPERATION_DELETE
|
||||
*
|
||||
* @return TemporaryObjectDescriptor|null
|
||||
*/
|
||||
public function CreateTemporaryObject(string $sTempId, string $sObjectClass, string $sObjectKey, string $sOperation): ?TemporaryObjectDescriptor
|
||||
{
|
||||
$result = $this->oTemporaryObjectRepository->Create($sTempId, $sObjectClass, $sObjectKey, $sOperation);
|
||||
|
||||
// Log
|
||||
IssueLog::Debug("TemporaryObjectsManager: Create a temporary object attached to temporary id $sTempId", LogChannels::TEMPORARY_OBJECTS, [
|
||||
'temp_id' => $sTempId,
|
||||
'item_class' => $sObjectClass,
|
||||
'item_id' => $sObjectKey,
|
||||
'succeeded' => $result != null,
|
||||
]);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the ongoing operation (create or delete) on all the temporary objects impacted by this transaction id
|
||||
*
|
||||
* @param string $sTransactionId form transaction id
|
||||
*
|
||||
* @return bool true if success
|
||||
*/
|
||||
public function CancelAllTemporaryObjects(string $sTransactionId): bool
|
||||
{
|
||||
try {
|
||||
// Get temporary object descriptors
|
||||
$oDbObjectSet = $this->oTemporaryObjectRepository->SearchByTempId($sTransactionId, true);
|
||||
|
||||
// Cancel temporary objects...
|
||||
$bResult = $this->CancelTemporaryObjects($oDbObjectSet->ToArray());
|
||||
|
||||
// Log
|
||||
IssueLog::Debug("TemporaryObjectsManager: Cancel all temporary objects attached to temporary id $sTransactionId", LogChannels::TEMPORARY_OBJECTS, [
|
||||
'temp_id' => $sTransactionId,
|
||||
'succeeded' => $bResult,
|
||||
]);
|
||||
|
||||
// return operation success
|
||||
return true;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
ExceptionLog::LogException($e);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the ongoing operation (create or delete) on the given temporary objects
|
||||
*
|
||||
* @param array{\TemporaryObjectDescriptor} $aTemporaryObjectDescriptor
|
||||
*
|
||||
* @return bool true if success
|
||||
*/
|
||||
private function CancelTemporaryObjects(array $aTemporaryObjectDescriptor): bool
|
||||
{
|
||||
try {
|
||||
// All operations succeeded
|
||||
$bResult = true;
|
||||
|
||||
/** @var TemporaryObjectDescriptor $oTemporaryObjectDescriptor */
|
||||
foreach ($aTemporaryObjectDescriptor as $oTemporaryObjectDescriptor) {
|
||||
|
||||
// Cancel temporary objects
|
||||
if (!$this->CancelTemporaryObject($oTemporaryObjectDescriptor)) {
|
||||
$bResult = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
ExceptionLog::LogException($e);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extends the temporary object descriptor lifetime
|
||||
*
|
||||
* @param string $sTransactionId
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ExtendTemporaryObjectsLifetime(string $sTransactionId): bool
|
||||
{
|
||||
try {
|
||||
// Create db set from db search
|
||||
$oDbObjectSet = $this->oTemporaryObjectRepository->SearchByTempId($sTransactionId);
|
||||
|
||||
// Expiration date
|
||||
$iExpirationDate = time() + TemporaryObjectConfig::GetInstance()->GetConfigTemporaryLifetime();
|
||||
|
||||
// Delay objects expiration
|
||||
while ($oObject = $oDbObjectSet->Fetch()) {
|
||||
$oObject->Set('expiration_date', $iExpirationDate);
|
||||
$oObject->DBUpdate();
|
||||
}
|
||||
|
||||
// Log
|
||||
$date = new DateTime();
|
||||
$date->setTimestamp($iExpirationDate);
|
||||
IssueLog::Debug("TemporaryObjectsManager: Delay all temporary objects descriptors expiration date attached to temporary id $sTransactionId", LogChannels::TEMPORARY_OBJECTS, [
|
||||
'temp_id' => $sTransactionId,
|
||||
'expiration_date' => date_format($date, 'Y-m-d H:i:s'),
|
||||
'total_temporary_objects' => $this->oTemporaryObjectRepository->CountTemporaryObjectsByTempId($sTransactionId),
|
||||
]);
|
||||
|
||||
// return operation success
|
||||
return true;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
ExceptionLog::LogException($e);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept all the temporary objects operations
|
||||
*
|
||||
* @param string $sTransactionId
|
||||
*
|
||||
* @return void
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
private function FinalizeTemporaryObjects(string $sTransactionId)
|
||||
{
|
||||
// All operations succeeded
|
||||
$bResult = true;
|
||||
|
||||
// Get temporary object descriptors
|
||||
$oDBObjectSet = $this->oTemporaryObjectRepository->SearchByTempId($sTransactionId, true);
|
||||
|
||||
// Iterate throw descriptors...
|
||||
/** @var TemporaryObjectDescriptor $oTemporaryObjectDescriptor */
|
||||
while ($oTemporaryObjectDescriptor = $oDBObjectSet->Fetch()) {
|
||||
// Retrieve attributes values
|
||||
$sHostClass = $oTemporaryObjectDescriptor->Get('host_class');
|
||||
$sHostId = $oTemporaryObjectDescriptor->Get('host_id');
|
||||
|
||||
// No host object
|
||||
if ($sHostId === 0) {
|
||||
$bResult = $bResult && $this->CancelTemporaryObject($oTemporaryObjectDescriptor);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Host object pointed by descriptor doesn't exist anymore
|
||||
$oHostObject = MetaModel::GetObject($sHostClass, $sHostId, false);
|
||||
if (is_null($oHostObject)) {
|
||||
$bResult = $bResult && $this->CancelTemporaryObject($oTemporaryObjectDescriptor);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise confirm
|
||||
$bResult = $bResult && $this->ConfirmTemporaryObject($oTemporaryObjectDescriptor);
|
||||
}
|
||||
|
||||
// Log
|
||||
IssueLog::Debug("TemporaryObjectsManager: Finalize all temporary objects attached to temporary id $sTransactionId", LogChannels::TEMPORARY_OBJECTS, [
|
||||
'temp_id' => $sTransactionId,
|
||||
'succeeded' => $bResult,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept operation on the given temporary object
|
||||
*
|
||||
* @param TemporaryObjectDescriptor $oTemporaryObjectDescriptor
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function ConfirmTemporaryObject(TemporaryObjectDescriptor $oTemporaryObjectDescriptor): bool
|
||||
{
|
||||
try {
|
||||
// Retrieve attributes values
|
||||
$sOperation = $oTemporaryObjectDescriptor->Get('operation');
|
||||
$sItemClass = $oTemporaryObjectDescriptor->Get('item_class');
|
||||
$sItemId = $oTemporaryObjectDescriptor->Get('item_id');
|
||||
|
||||
// Get temporary object
|
||||
$oTemporaryObject = MetaModel::GetObject($sItemClass, $sItemId);
|
||||
|
||||
if ($sOperation === TemporaryObjectHelper::OPERATION_DELETE) {
|
||||
// Delete temporary object
|
||||
$oTemporaryObject->DBDelete();
|
||||
IssueLog::Info("Temporary Object [$sItemClass:$sItemId] removed (operation: $sOperation)", LogChannels::TEMPORARY_OBJECTS, utils::GetStackTraceAsArray());
|
||||
} elseif ($sOperation === TemporaryObjectHelper::OPERATION_CREATE) {
|
||||
// Send an event in case of creation confirmation
|
||||
$oTemporaryObject->FireEvent(TemporaryObjectsEvents::TEMPORARY_OBJECT_EVENT_CONFIRM_CREATE);
|
||||
}
|
||||
|
||||
// Remove temporary object descriptor entry
|
||||
$oTemporaryObjectDescriptor->DBDelete();
|
||||
|
||||
// Log
|
||||
IssueLog::Debug("Temporary Object [$sItemClass:$sItemId] $sOperation confirmed", LogChannels::TEMPORARY_OBJECTS, utils::GetStackTraceAsArray());
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
ExceptionLog::LogException($e);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CancelTemporaryObject.
|
||||
*
|
||||
* @param TemporaryObjectDescriptor $oTemporaryObjectDescriptor
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function CancelTemporaryObject(TemporaryObjectDescriptor $oTemporaryObjectDescriptor): bool
|
||||
{
|
||||
try {
|
||||
// Retrieve attributes values
|
||||
$sOperation = $oTemporaryObjectDescriptor->Get('operation');
|
||||
$sItemClass = $oTemporaryObjectDescriptor->Get('item_class');
|
||||
$sItemId = $oTemporaryObjectDescriptor->Get('item_id');
|
||||
|
||||
if ($sOperation === TemporaryObjectHelper::OPERATION_CREATE) {
|
||||
|
||||
// Get temporary object
|
||||
$oTemporaryObject = MetaModel::GetObject($sItemClass, $sItemId, false);
|
||||
|
||||
// Delete temporary object
|
||||
if (!is_null($oTemporaryObject)) {
|
||||
$oTemporaryObject->DBDelete();
|
||||
}
|
||||
|
||||
IssueLog::Info("Temporary Object [$sItemClass:$sItemId] removed (operation: $sOperation)", LogChannels::TEMPORARY_OBJECTS, utils::GetStackTraceAsArray());
|
||||
}
|
||||
|
||||
// Remove temporary object descriptor entry
|
||||
$oTemporaryObjectDescriptor->DBDelete();
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
ExceptionLog::LogException($e);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle temporary objects.
|
||||
*
|
||||
* @param \DBObject $oDBObject
|
||||
* @param array $aContext
|
||||
*
|
||||
* @return void
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function HandleTemporaryObjects(DBObject $oDBObject, array $aContext)
|
||||
{
|
||||
if (array_key_exists('create', $aContext)) {
|
||||
// Retrieve context information
|
||||
$aContextCreation = $aContext['create'];
|
||||
$sTransactionId = $aContextCreation['transaction_id'] ?? null;
|
||||
$sHostClass = $aContextCreation['host_class'] ?? null;
|
||||
$sHostAttCode = $aContextCreation['host_att_code'] ?? null;
|
||||
|
||||
// Security
|
||||
if (is_null($sTransactionId) || is_null($sHostClass) || is_null($sHostAttCode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get host class attribute definition
|
||||
try {
|
||||
$oAttDef = MetaModel::GetAttributeDef($sHostClass, $sHostAttCode);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
ExceptionLog::LogException($e);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If creation as temporary object requested or force for all objects
|
||||
if (($oAttDef->IsParam('create_temporary_object') && $oAttDef->Get('create_temporary_object'))
|
||||
|| TemporaryObjectConfig::GetInstance()->GetConfigTemporaryForce()) {
|
||||
|
||||
$this->CreateTemporaryObject($sTransactionId, get_class($oDBObject), $oDBObject->GetKey(), TemporaryObjectHelper::OPERATION_CREATE);
|
||||
}
|
||||
}
|
||||
if (array_key_exists('finalize', $aContext)) {
|
||||
// Retrieve context information
|
||||
$aContextFinalize = $aContext['finalize'];
|
||||
$sTransactionId = $aContextFinalize['transaction_id'] ?? null;
|
||||
|
||||
// validate temporary objects
|
||||
$this->FinalizeTemporaryObjects($sTransactionId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GarbageExpiredTemporaryObjects.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function GarbageExpiredTemporaryObjects(): bool
|
||||
{
|
||||
try {
|
||||
// Search for expired temporary objects
|
||||
$oDBObjectSet = $this->oTemporaryObjectRepository->SearchByExpired();
|
||||
|
||||
// Cancel temporary objects
|
||||
$this->CancelTemporaryObjects($oDBObjectSet->ToArray());
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
ExceptionLog::LogException($e);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
203
sources/Service/TemporaryObjects/TemporaryObjectRepository.php
Normal file
203
sources/Service/TemporaryObjects/TemporaryObjectRepository.php
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Service\TemporaryObjects;
|
||||
|
||||
use AttributeDateTime;
|
||||
use DBObjectSet;
|
||||
use DBSearch;
|
||||
use Exception;
|
||||
use ExceptionLog;
|
||||
use MetaModel;
|
||||
use TemporaryObjectDescriptor;
|
||||
|
||||
/**
|
||||
* TemporaryObjectRepository.
|
||||
*
|
||||
* Repository class to perform ORM tasks.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
class TemporaryObjectRepository
|
||||
{
|
||||
/** @var TemporaryObjectRepository|null Singleton */
|
||||
static private ?TemporaryObjectRepository $oSingletonInstance = null;
|
||||
|
||||
/**
|
||||
* GetInstance.
|
||||
*
|
||||
* @return TemporaryObjectRepository
|
||||
*/
|
||||
public static function GetInstance(): TemporaryObjectRepository
|
||||
{
|
||||
if (is_null(self::$oSingletonInstance)) {
|
||||
self::$oSingletonInstance = new TemporaryObjectRepository();
|
||||
}
|
||||
|
||||
return self::$oSingletonInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Create.
|
||||
*
|
||||
* @param string $sTempId Temporary id
|
||||
* @param string $sObjectClass Object class
|
||||
* @param string $sObjectKey Object key
|
||||
* @param string $sOperation temporary operation on file TemporaryObjectHelper::OPERATION_CREATE or TemporaryObjectHelper::OPERATION_DELETE
|
||||
*
|
||||
* @return TemporaryObjectDescriptor|null
|
||||
*/
|
||||
public function Create(string $sTempId, string $sObjectClass, string $sObjectKey, string $sOperation): ?TemporaryObjectDescriptor
|
||||
{
|
||||
try {
|
||||
if (!MetaModel::IsValidClass($sObjectClass)) {
|
||||
throw new Exception("Class $sObjectClass is not a valid class");
|
||||
}
|
||||
if (MetaModel::GetObject($sObjectClass, $sObjectKey, false) === false) {
|
||||
throw new Exception("Object $sObjectClass:$sObjectKey is not a valid object");
|
||||
}
|
||||
|
||||
// Create a temporary object descriptor
|
||||
/** @var \TemporaryObjectDescriptor $oTemporaryObjectDescriptor */
|
||||
$oTemporaryObjectDescriptor = MetaModel::NewObject(TemporaryObjectDescriptor::class, [
|
||||
'operation' => $sOperation,
|
||||
'temp_id' => $sTempId,
|
||||
'expiration_date' => time() + TemporaryObjectConfig::GetInstance()->GetConfigTemporaryLifetime(),
|
||||
'item_class' => $sObjectClass,
|
||||
'item_id' => $sObjectKey,
|
||||
]);
|
||||
$oTemporaryObjectDescriptor->DBInsert();
|
||||
|
||||
return $oTemporaryObjectDescriptor;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
|
||||
ExceptionLog::LogException($e);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SearchByTempId.
|
||||
*
|
||||
* @param string $sTempId temporary id
|
||||
* @param bool $bReverseOrder reverse order of result
|
||||
*
|
||||
* @return \DBObjectSet
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function SearchByTempId(string $sTempId, bool $bReverseOrder = false): DBObjectSet
|
||||
{
|
||||
// Prepare OQL
|
||||
$sOQL = sprintf('SELECT `%s` WHERE temp_id=:temp_id', TemporaryObjectDescriptor::class);
|
||||
|
||||
// Create db search
|
||||
$oDbObjectSearch = DBSearch::FromOQL($sOQL);
|
||||
|
||||
// Create db set from db search
|
||||
$oDbObjectSet = new DBObjectSet($oDbObjectSearch, [], [
|
||||
'temp_id' => $sTempId,
|
||||
]);
|
||||
|
||||
// Reverse order
|
||||
if ($bReverseOrder) {
|
||||
$oDbObjectSet->SetOrderBy([
|
||||
'id' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
return $oDbObjectSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* SearchByItem.
|
||||
*
|
||||
* @param string $sItemClass
|
||||
* @param string $sItemId
|
||||
* @param bool $bReverseOrder reverse order of result
|
||||
*
|
||||
* @return \DBObjectSet
|
||||
* @throws \MySQLException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function SearchByItem(string $sItemClass, string $sItemId, bool $bReverseOrder = false): DBObjectSet
|
||||
{
|
||||
// Prepare OQL
|
||||
$sOQL = sprintf('SELECT `%s` WHERE item_class=:item_class AND item_id=:item_id', TemporaryObjectDescriptor::class);
|
||||
|
||||
// Create db search
|
||||
$oDbObjectSearch = DBSearch::FromOQL($sOQL);
|
||||
|
||||
// Create db set from db search
|
||||
$oDbObjectSet = new DBObjectSet($oDbObjectSearch, [], [
|
||||
'item_class' => $sItemClass,
|
||||
'item_id' => $sItemId,
|
||||
]);
|
||||
|
||||
// Reverse order
|
||||
if ($bReverseOrder) {
|
||||
$oDbObjectSet->SetOrderBy([
|
||||
'id' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
return $oDbObjectSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* CountTemporaryObjectsByTempId.
|
||||
*
|
||||
* @param string $sTempId
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function CountTemporaryObjectsByTempId(string $sTempId): int
|
||||
{
|
||||
try {
|
||||
|
||||
$oDbObjectSet = $this->SearchByTempId($sTempId);
|
||||
|
||||
// return operation success
|
||||
return $oDbObjectSet->count();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
|
||||
ExceptionLog::LogException($e);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SearchByExpired.
|
||||
*
|
||||
* @return DBObjectSet
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function SearchByExpired(): DBObjectSet
|
||||
{
|
||||
// Prepare OQL
|
||||
$sOQL = sprintf('SELECT `%s` WHERE expiration_date<:now', TemporaryObjectDescriptor::class);
|
||||
|
||||
// Create db search
|
||||
$oDbObjectSearch = DBSearch::FromOQL($sOQL);
|
||||
|
||||
// Create db set from db search
|
||||
$sDateNow = date(AttributeDateTime::GetSQLFormat(), time());
|
||||
|
||||
return new DBObjectSet($oDbObjectSearch, ['id' => false], ['now' => $sDateNow]);
|
||||
}
|
||||
}
|
||||
47
sources/Service/TemporaryObjects/TemporaryObjectsEvents.php
Normal file
47
sources/Service/TemporaryObjects/TemporaryObjectsEvents.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Service\TemporaryObjects;
|
||||
|
||||
use Combodo\iTop\Service\Events\Description\EventDataDescription;
|
||||
use Combodo\iTop\Service\Events\Description\EventDescription;
|
||||
use Combodo\iTop\Service\Events\EventService;
|
||||
use Combodo\iTop\Service\Events\iEventServiceSetup;
|
||||
|
||||
class TemporaryObjectsEvents implements iEventServiceSetup
|
||||
{
|
||||
|
||||
// Startup events
|
||||
const TEMPORARY_OBJECT_EVENT_CONFIRM_CREATE = 'TEMPORARY_OBJECT_EVENT_CONFIRM_CREATE';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function RegisterEventsAndListeners()
|
||||
{
|
||||
EventService::RegisterEvent(new EventDescription(
|
||||
self::TEMPORARY_OBJECT_EVENT_CONFIRM_CREATE,
|
||||
[
|
||||
'cmdbAbstractObject' => 'cmdbAbstractObject',
|
||||
],
|
||||
'The MetaModel is fully started',
|
||||
'',
|
||||
[
|
||||
new EventDataDescription(
|
||||
'object',
|
||||
'The object concerned by the creation confirmation',
|
||||
'DBObject',
|
||||
),
|
||||
new EventDataDescription(
|
||||
'debug_info',
|
||||
'Debug string',
|
||||
'string',
|
||||
),
|
||||
],
|
||||
'application'));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user