transaction.class.inc.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. <?php
  2. // Copyright (C) 2010 Combodo SARL
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; version 3 of the License.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. /**
  17. * This class records the pending "transactions" corresponding to forms that have not been
  18. * submitted yet, in order to prevent double submissions. When created a transaction remains valid
  19. * until it is "used" by calling IsTransactionValid once, or until it
  20. * expires (delay = TRANSACTION_EXPIRATION_DELAY, defaults to 4 hours)
  21. * @package iTop
  22. */
  23. // How long a "transaction" is considered valid, i.e. when a form is submitted
  24. // if the form dates back from too long a time, it is considered invalid. This is
  25. // because since HTTP is not a connected protocol, we cannot know when a user disconnects
  26. // from the application (maybe just by closing her browser), so we keep track - in the database - of all pending
  27. // forms that have not yet been submitted. To limit this list we consider that after some time
  28. // a "transaction" is no loger valid an gets purged from the table
  29. define ('TRANSACTION_EXPIRATION_DELAY', 3600*4); // default: 4h
  30. require_once('../core/dbobject.class.php');
  31. class privUITransaction extends DBObject
  32. {
  33. public static function Init()
  34. {
  35. $aParams = array
  36. (
  37. "category" => "gui",
  38. "key_type" => "autoincrement",
  39. "name_attcode" => "expiration_date",
  40. "state_attcode" => "",
  41. "reconc_keys" => array(),
  42. "db_table" => "priv_transaction",
  43. "db_key_field" => "id",
  44. "db_finalclass_field" => "",
  45. );
  46. MetaModel::Init_Params($aParams);
  47. MetaModel::Init_AddAttribute(new AttributeDateTime("expiration_date", array("allowed_values"=>null, "sql"=>"expiration_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
  48. MetaModel::Init_SetZListItems('details', array('expiration_date')); // Attributes to be displayed for the complete details
  49. MetaModel::Init_SetZListItems('list', array('expiration_date')); // Attributes to be displayed for a list
  50. }
  51. /**
  52. * Create a new transaction, store it in the database and return its id
  53. * @param void
  54. * @return int The identifier of the new transaction
  55. */
  56. public static function GetNewTransactionId()
  57. {
  58. // First remove all the expired transactions...
  59. self::CleanupExpiredTransactions();
  60. $oTransaction = new privUITransaction();
  61. $sDate = date('Y-m-d H:i:s', time()+TRANSACTION_EXPIRATION_DELAY);
  62. $oTransaction->Set('expiration_date', $sDate); // 4 h delay by default
  63. $oTransaction->DBInsert();
  64. return sprintf("%d", $oTransaction->GetKey());
  65. }
  66. /**
  67. * Check whether a transaction is valid or not and remove the valid transaction from
  68. * the database so that another call to IsTransactionValid for the same transaction
  69. * will return false
  70. * @param int $id Identifier of the transaction, as returned by GetNewTransactionId
  71. * @return bool True if the transaction is valid, false otherwise
  72. */
  73. public static function IsTransactionValid($id)
  74. {
  75. // First remove all the expired transactions...
  76. self::CleanupExpiredTransactions();
  77. // TO DO put a critical section around this part to be 100% safe...
  78. // sem_acquire(...)
  79. $bResult = false;
  80. $oTransaction = MetaModel::GetObject('privUITransaction', $id, false /* MustBeFound */);
  81. if ($oTransaction)
  82. {
  83. $bResult = true;
  84. $oTransaction->DBDelete();
  85. }
  86. // sem_release(...)
  87. return $bResult;
  88. }
  89. /**
  90. * Remove from the database all transactions that have expired
  91. */
  92. protected static function CleanupExpiredTransactions()
  93. {
  94. $sQuery = 'SELECT privUITransaction WHERE expiration_date < NOW()';
  95. $oSearch = DBObjectSearch::FromOQL($sQuery);
  96. $oSet = new DBObjectSet($oSearch);
  97. while($oTransaction = $oSet->Fetch())
  98. {
  99. $oTransaction->DBDelete();
  100. }
  101. }
  102. }
  103. ?>