BxDolLiveUpdates.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
  4. * CC-BY License - http://creativecommons.org/licenses/by/3.0/
  5. *
  6. * @defgroup DolphinCore Dolphin Core
  7. * @{
  8. */
  9. bx_import('BxDol');
  10. bx_import('BxDolLiveUpdatesQuery');
  11. /**
  12. * @page objects
  13. * @section live updates Live Updates
  14. * @ref BxDolLiveUpdates
  15. */
  16. class BxDolLiveUpdates extends BxDol
  17. {
  18. protected $_oQuery;
  19. protected $_aSystems;
  20. protected $_iInterval;
  21. protected $_sSessionKey;
  22. protected $_iCacheTTL; // Note. Non-zero value may lead to cache destroying in wrong time.
  23. protected $_sCacheKey;
  24. protected $_sJsClass;
  25. protected $_sJsObject;
  26. public function __construct()
  27. {
  28. parent::__construct();
  29. $this->_oQuery = new BxDolLiveUpdatesQuery();
  30. $this->_aSystems = $this->_oQuery->getSystems();
  31. $this->_iInterval = (int)$this->_oQuery->getParam('sys_live_updates_interval');
  32. $this->_sSessionKey = 'bx_lu_index';
  33. $this->_iCacheTTL = 0;
  34. $this->_sCacheKey = 'sys_live_updates_' . bx_get_logged_profile_id();
  35. $this->_sJsClass = 'BxDolLiveUpdates';
  36. $this->_sJsObject = 'oLiveUpdates';
  37. }
  38. /**
  39. * get live updates instanse
  40. * @return ready to use class instance
  41. */
  42. public static function getInstance()
  43. {
  44. if(!isset($GLOBALS['bxDolClasses'][__CLASS__])) {
  45. bx_import('BxTemplLiveUpdates');
  46. $GLOBALS['bxDolClasses'][__CLASS__] = new BxTemplLiveUpdates();
  47. }
  48. return $GLOBALS['bxDolClasses'][__CLASS__];
  49. }
  50. /**
  51. *
  52. * Is called via Ajax Requests only.
  53. */
  54. public function perform()
  55. {
  56. $iIndex = $this->_getIndex();
  57. $this->_aSystems = $this->_getCachedSystems();
  58. if(empty($this->_aSystems) || !is_array($this->_aSystems))
  59. return array();
  60. $aCached = $this->_getCachedData();
  61. $aRequested = $this->_getRequestedData($iIndex, true, $aCached);
  62. $aResult = array();
  63. $bUpdateCache = false;
  64. foreach($aRequested as $sName => $aData) {
  65. if(isset($aCached[$sName]) && (int)$aCached[$sName] == (int)$aData['count'])
  66. continue;
  67. $aResultData = array('count_new' => $aData['count'], 'count_old' => $aCached[$sName]);
  68. if(isset($aData['data']))
  69. $aResultData = array_merge($aResultData, $aData['data']);
  70. $aResult[] = array(
  71. 'data' => $aResultData,
  72. 'method' => $aData['method']
  73. );
  74. $aCached[$sName] = $aData['count'];
  75. $bUpdateCache = true;
  76. }
  77. if($bUpdateCache)
  78. $this->_updateCached('data', $aCached);
  79. return $aResult;
  80. }
  81. /**
  82. *
  83. * Add transient live update for current user on this current page.
  84. * @param string $sName - unique name.
  85. * @param integer $iFrequency - call frequency.
  86. * @param string $sServiceCall - serialized service call.
  87. * @param boolean $bActive - add active/not active live update.
  88. */
  89. public function add($sName, $iFrequency, $sServiceCall, $bActive = true)
  90. {
  91. if(isset($this->_aSystems[$sName]))
  92. return false;
  93. $this->_aSystems[$sName] = array(
  94. 'name' => $sName,
  95. 'frequency' => $iFrequency,
  96. 'service_call' => $sServiceCall,
  97. 'active' => $bActive ? 1 : 0
  98. );
  99. $this->_updateCached('systems', $this->_aSystems);
  100. return true;
  101. }
  102. protected function _getIndex()
  103. {
  104. bx_import('BxDolSession');
  105. $oSession = BxDolSession::getInstance();
  106. $iIndex = (int)$oSession->getValue($this->_sSessionKey);
  107. $oSession->setValue($this->_sSessionKey, ($iIndex + 1));
  108. return $iIndex;
  109. }
  110. protected function _getCacheInfo()
  111. {
  112. return array(
  113. $this->_oQuery->getDbCacheObject(),
  114. $this->_oQuery->genDbCacheKey($this->_sCacheKey),
  115. $this->_iCacheTTL
  116. );
  117. }
  118. protected function _getCached($sType)
  119. {
  120. list($oCache, $sCacheKey, $iCacheTtl) = $this->_getCacheInfo();
  121. $aCached = $oCache->getData($sCacheKey, $iCacheTtl);
  122. if(empty($aCached[$sType])) {
  123. switch($sType) {
  124. case 'systems':
  125. $aCached[$sType] = $this->_oQuery->getSystems();
  126. break;
  127. case 'data':
  128. $aRequested = $this->_getRequestedData();
  129. foreach($aRequested as $sName => $aData)
  130. $aCached[$sType][$sName] = $aData['count'];
  131. break;
  132. }
  133. if(!empty($aCached[$sType]))
  134. $oCache->setData($sCacheKey, $aCached, $iCacheTtl);
  135. }
  136. return $aCached[$sType];
  137. }
  138. protected function _getCachedSystems()
  139. {
  140. return $this->_getCached('systems');
  141. }
  142. protected function _getCachedData()
  143. {
  144. return $this->_getCached('data');
  145. }
  146. protected function _updateCached($sKey, $aData)
  147. {
  148. list($oCache, $sCacheKey, $iCacheTtl) = $this->_getCacheInfo();
  149. $aCached = $oCache->getData($sCacheKey, $iCacheTtl);
  150. $aCached[$sKey] = $aData;
  151. $oCache->setData($sCacheKey, $aCached, $iCacheTtl);
  152. }
  153. protected function _getRequestedData($iIndex = 0, $bIndexCheck = false, $aCachedData = array())
  154. {
  155. $aResult = array();
  156. foreach($this->_aSystems as $aSystem) {
  157. if(empty($aSystem) || !is_array($aSystem) || (int)$aSystem['active'] != 1)
  158. continue;
  159. if($bIndexCheck && $iIndex % (int)$aSystem['frequency'] != 0)
  160. continue;
  161. if(!BxDolService::isSerializedService($aSystem['service_call']))
  162. continue;
  163. $aMarkers = array();
  164. if(!empty($aCachedData) && isset($aCachedData[$aSystem['name']]))
  165. $aMarkers = array('count' => (int)$aCachedData[$aSystem['name']]);
  166. $aResponce = BxDolService::callSerialized($aSystem['service_call'], $aMarkers);
  167. if(empty($aResponce) || !is_array($aResponce) || !isset($aResponce['count'], $aResponce['method']))
  168. continue;
  169. $aResult[$aSystem['name']] = $aResponce;
  170. }
  171. return $aResult;
  172. }
  173. }
  174. /** @} */