diff --git a/application/transaction.class.inc.php b/application/transaction.class.inc.php index 39db22201..58e7f3952 100644 --- a/application/transaction.class.inc.php +++ b/application/transaction.class.inc.php @@ -17,94 +17,57 @@ /** * This class records the pending "transactions" corresponding to forms that have not been * submitted yet, in order to prevent double submissions. When created a transaction remains valid - * until it is "used" by calling IsTransactionValid once, or until it - * expires (delay = TRANSACTION_EXPIRATION_DELAY, defaults to 4 hours) + * until the user's session expires * @package iTop */ -// How long a "transaction" is considered valid, i.e. when a form is submitted -// if the form dates back from too long a time, it is considered invalid. This is -// because since HTTP is not a connected protocol, we cannot know when a user disconnects -// from the application (maybe just by closing her browser), so we keep track - in the database - of all pending -// forms that have not yet been submitted. To limit this list we consider that after some time -// a "transaction" is no loger valid an gets purged from the table -define ('TRANSACTION_EXPIRATION_DELAY', 3600*4); // default: 4h -require_once('../core/dbobject.class.php'); -class privUITransaction extends DBObject +class privUITransaction { - public static function Init() - { - $aParams = array - ( - "category" => "gui", - "key_type" => "autoincrement", - "name_attcode" => "expiration_date", - "state_attcode" => "", - "reconc_keys" => array(), - "db_table" => "priv_transaction", - "db_key_field" => "id", - "db_finalclass_field" => "", - ); - MetaModel::Init_Params($aParams); - MetaModel::Init_AddAttribute(new AttributeDateTime("expiration_date", array("allowed_values"=>null, "sql"=>"expiration_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); - - MetaModel::Init_SetZListItems('details', array('expiration_date')); // Attributes to be displayed for the complete details - MetaModel::Init_SetZListItems('list', array('expiration_date')); // Attributes to be displayed for a list - } /** - * Create a new transaction, store it in the database and return its id + * Create a new transaction id, store it in the session and return its id * @param void * @return int The identifier of the new transaction */ public static function GetNewTransactionId() { - // First remove all the expired transactions... - self::CleanupExpiredTransactions(); - $oTransaction = new privUITransaction(); - $sDate = date('Y-m-d H:i:s', time()+TRANSACTION_EXPIRATION_DELAY); - $oTransaction->Set('expiration_date', $sDate); // 4 h delay by default - $oTransaction->DBInsert(); - return sprintf("%d", $oTransaction->GetKey()); + if (!isset($_SESSION['transactions'])) + { + $_SESSION['transactions'] = array(); + } + // Strictly speaking, the two lines below should be grouped together + // by a critical section + // sem_acquire($rSemIdentified); + $id = 1 + count($_SESSION['transactions']); + $_SESSION['transactions'][$id] = true; + // sem_release($rSemIdentified); + + return sprintf("%d", $id); } /** * Check whether a transaction is valid or not and remove the valid transaction from - * the database so that another call to IsTransactionValid for the same transaction + * the session so that another call to IsTransactionValid for the same transaction id * will return false * @param int $id Identifier of the transaction, as returned by GetNewTransactionId * @return bool True if the transaction is valid, false otherwise */ public static function IsTransactionValid($id) { - // First remove all the expired transactions... - self::CleanupExpiredTransactions(); - // TO DO put a critical section around this part to be 100% safe... - // sem_acquire(...) - $bResult = false; - $oTransaction = MetaModel::GetObject('privUITransaction', $id, false /* MustBeFound */); - if ($oTransaction) + $bResult = false; + if (isset($_SESSION['transactions'])) { - $bResult = true; - $oTransaction->DBDelete(); + // Strictly speaking, the three lines below should be grouped together + // inside the same critical section as above + // sem_acquire($rSemIdentified); + if (isset($_SESSION['transactions'][$id])) + { + $bResult = true; + unset($_SESSION['transactions'][$id]); + } + // sem_release($rSemIdentified); } - // sem_release(...) return $bResult; } - - /** - * Remove from the database all transactions that have expired - */ - protected static function CleanupExpiredTransactions() - { - $sQuery = 'SELECT privUITransaction WHERE expiration_date < NOW()'; - $oSearch = DBObjectSearch::FromOQL($sQuery); - $oSet = new DBObjectSet($oSearch); - while($oTransaction = $oSet->Fetch()) - { - $oTransaction->DBDelete(); - } - } - } ?>