BxDolSession.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup UnaCore UNA Core
  7. * @{
  8. */
  9. if (!defined('BX_DOL_SESSION_LIFETIME'))
  10. define('BX_DOL_SESSION_LIFETIME', 3600);
  11. define('BX_DOL_SESSION_COOKIE', 'memberSession');
  12. class BxDolSession extends BxDolFactory implements iBxDolSingleton
  13. {
  14. protected $oDb;
  15. protected $sId;
  16. protected $iUserId;
  17. protected $aData;
  18. protected $bAutoLogout; //--- Auto logout with broken session
  19. protected function __construct()
  20. {
  21. if (isset($GLOBALS['bxDolClasses'][get_class($this)]))
  22. trigger_error ('Multiple instances are not allowed for the class: ' . get_class($this), E_USER_ERROR);
  23. parent::__construct();
  24. $this->oDb = new BxDolSessionQuery();
  25. $this->sId = '';
  26. $this->iUserId = 0;
  27. $this->aData = array();
  28. $this->bAutoLogout = false; // when changing to 'true', it's better to increase BX_DOL_SESSION_LIFETIME to 1 month or so
  29. if (defined('BX_SESSION_AUTO_LOGOUT'))
  30. $this->bAutoLogout = BX_SESSION_AUTO_LOGOUT;
  31. }
  32. /**
  33. * Prevent cloning the instance
  34. */
  35. public function __clone()
  36. {
  37. if (isset($GLOBALS['bxDolClasses'][get_class($this)]))
  38. trigger_error('Clone is not allowed for the class: ' . get_class($this), E_USER_ERROR);
  39. }
  40. /**
  41. * Get singleton instance of the class
  42. */
  43. public static function getInstance()
  44. {
  45. if(!isset($GLOBALS['bxDolClasses'][__CLASS__]))
  46. $GLOBALS['bxDolClasses'][__CLASS__] = new BxDolSession();
  47. if(!$GLOBALS['bxDolClasses'][__CLASS__]->getId())
  48. $GLOBALS['bxDolClasses'][__CLASS__]->start();
  49. return $GLOBALS['bxDolClasses'][__CLASS__];
  50. }
  51. function start()
  52. {
  53. if (defined('BX_DOL_CRON_EXECUTE'))
  54. return true;
  55. if ($this->exists($this->sId)) {
  56. if ($this->iUserId == getLoggedId())
  57. return true;
  58. $this->destroy(false);
  59. }
  60. /**
  61. * Force logout a logged in user if his session wasn't found and required to be automatically recreated.
  62. * It's needed to avoid problems when different users are logged in at the same time under one account.
  63. */
  64. if($this->bAutoLogout && isLogged())
  65. bx_logout();
  66. $this->sId = genRndPwd(32, true);
  67. $aUrl = parse_url(BX_DOL_URL_ROOT);
  68. $sPath = isset($aUrl['path']) && !empty($aUrl['path']) ? $aUrl['path'] : '/';
  69. setcookie(BX_DOL_SESSION_COOKIE, $this->sId, 0, $sPath, '', false, true);
  70. $this->save();
  71. return true;
  72. }
  73. function destroy($bDeleteCookies = true)
  74. {
  75. if ($bDeleteCookies) {
  76. $aUrl = parse_url(BX_DOL_URL_ROOT);
  77. $sPath = isset($aUrl['path']) && !empty($aUrl['path']) ? $aUrl['path'] : '/';
  78. setcookie(BX_DOL_SESSION_COOKIE, '', time() - 86400, $sPath, '', false, true);
  79. unset($_COOKIE[BX_DOL_SESSION_COOKIE]);
  80. }
  81. $this->oDb->delete($this->sId);
  82. $this->sId = '';
  83. $this->iUserId = 0;
  84. $this->aData = array();
  85. }
  86. function exists($sId = '')
  87. {
  88. if(empty($sId) && isset($_COOKIE[BX_DOL_SESSION_COOKIE]))
  89. $sId = bx_process_input($_COOKIE[BX_DOL_SESSION_COOKIE]);
  90. $mixedSession = $this->oDb->exists($sId);
  91. if($mixedSession === false)
  92. return false;
  93. $this->sId = $mixedSession['id'];
  94. $this->iUserId = (int)$mixedSession['user_id'];
  95. $this->aData = unserialize($mixedSession['data']);
  96. $this->oDb->update($this->sId); //--- update session's time
  97. return true;
  98. }
  99. function getId()
  100. {
  101. return $this->sId;
  102. }
  103. function setUserId($iUserId)
  104. {
  105. $this->iUserId = $iUserId;
  106. $this->save();
  107. }
  108. function setValue($sKey, $mixedValue)
  109. {
  110. if(empty($this->sId))
  111. $this->start();
  112. $this->aData[$sKey] = $mixedValue;
  113. $this->save();
  114. }
  115. function unsetValue($sKey)
  116. {
  117. if(empty($this->sId))
  118. $this->start();
  119. unset($this->aData[$sKey]);
  120. if(!empty($this->aData))
  121. $this->save();
  122. else
  123. $this->destroy();
  124. }
  125. function isValue($sKey)
  126. {
  127. if(empty($this->sId))
  128. $this->start();
  129. return isset($this->aData[$sKey]);
  130. }
  131. function getValue($sKey)
  132. {
  133. if(empty($this->sId))
  134. $this->start();
  135. return isset($this->aData[$sKey]) ? $this->aData[$sKey] : false;
  136. }
  137. function getUnsetValue($sKey)
  138. {
  139. $mixedValue = $this->getValue($sKey);
  140. if($mixedValue !== false)
  141. $this->unsetValue($sKey);
  142. return $mixedValue;
  143. }
  144. public function maintenance()
  145. {
  146. return $this->oDb->deleteExpired();
  147. }
  148. protected function save()
  149. {
  150. if($this->iUserId == 0)
  151. $this->iUserId = getLoggedId();
  152. $this->oDb->save($this->sId, array(
  153. 'user_id' => $this->iUserId,
  154. 'data' => serialize($this->aData)
  155. ));
  156. }
  157. }
  158. /** @} */