BxDolAlerts.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <?php defined('BX_DOL') or defined('BX_DOL_INSTALL') 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. /**
  10. * Alert/Handler engine.
  11. *
  12. * Is needed to fire some alert(event) in one place and caught it with a handler somewhere else.
  13. *
  14. * Related classes:
  15. * BxDolAlertsResponse - abstract class for all response classes.
  16. * BxDolAlertsResponseUser - response class to process standard profile related alerts.
  17. *
  18. * Example of usage:
  19. * 1. Fire an alert
  20. *
  21. * @code
  22. * $oZ = new BxDolAlerts('unit_name', 'action', 'object_id', 'sender_id', 'extra_params');
  23. * $oZ->alert();
  24. * @endcode
  25. *
  26. * 2. Add handler and caught alert(s) @see BxDolAlertsResponseUser
  27. * a. Create Response class extending BxDolAlertsResponse class. It should process all necessary alerts which are passed to it.
  28. * b. Register your handler in the database by adding it in `sys_alerts_handlers` table.
  29. * c. Associate necessary alerts with the handler by adding them in the `sys_alerts` table.
  30. *
  31. *
  32. * Memberships/ACL:
  33. * Doesn't depend on user's membership.
  34. *
  35. *
  36. * Alerts:
  37. * no alerts available
  38. *
  39. */
  40. bx_import('BxDolDb');
  41. class BxDolAlerts extends BxDol
  42. {
  43. public $sUnit;
  44. public $sAction;
  45. public $iObject;
  46. public $iSender;
  47. public $aExtras;
  48. protected $_aAlerts;
  49. protected $_aHandlers;
  50. /**
  51. * Constructor
  52. * @param string $sType - system type
  53. * @param string $sAction - system action
  54. * @param int $iObjectId - object id
  55. * @param int $iSenderId - sender (action's author) profile id, if it is false - then currectly logged in profile id is used
  56. */
  57. public function __construct($sUnit, $sAction, $iObjectId, $iSender = false, $aExtras = array())
  58. {
  59. parent::__construct();
  60. if (getParam('sys_db_cache_enable')) {
  61. $oDb = BxDolDb::getInstance();
  62. $oCache = $oDb->getDbCacheObject();
  63. $sCacheKey = $oDb->genDbCacheKey('sys_alerts');
  64. $aData = $oCache->getData($sCacheKey);
  65. if (null === $aData) {
  66. $aData = $this->getAlertsData();
  67. $oCache->setData ($sCacheKey, $aData);
  68. }
  69. } else {
  70. $aData = $this->getAlertsData();
  71. }
  72. $this->_aAlerts = $aData['alerts'];
  73. $this->_aHandlers = $aData['handlers'];
  74. $this->sUnit = $sUnit;
  75. $this->sAction = $sAction;
  76. $this->iObject = (int)$iObjectId;
  77. $this->aExtras = $aExtras;
  78. if (false === $iSender) {
  79. $oProfile = BxDolProfile::getInstance();
  80. $this->iSender = $oProfile ? $oProfile->id() : 0;
  81. } else {
  82. $this->iSender = (int)$iSender;
  83. }
  84. }
  85. public static function cacheInvalidate()
  86. {
  87. return BxDolDb::getInstance()->cleanCache ('sys_alerts');
  88. }
  89. /**
  90. * Notifies the necessary handlers about the alert.
  91. */
  92. public function alert()
  93. {
  94. if (isset($this->_aAlerts[$this->sUnit]) && isset($this->_aAlerts[$this->sUnit][$this->sAction]))
  95. foreach($this->_aAlerts[$this->sUnit][$this->sAction] as $iHandlerId) {
  96. $aHandler = $this->_aHandlers[$iHandlerId];
  97. if (isset($GLOBALS['bx_profiler']) && 'bx_profiler' != $aHandler['name']) $GLOBALS['bx_profiler']->beginAlert($this->sUnit, $this->sAction, $aHandler['name']);
  98. if (!empty($aHandler['file']) && !empty($aHandler['class']) && file_exists(BX_DIRECTORY_PATH_ROOT . $aHandler['file'])) {
  99. if(!class_exists($aHandler['class'], false))
  100. require_once(BX_DIRECTORY_PATH_ROOT . $aHandler['file']);
  101. $oHandler = new $aHandler['class']();
  102. $oHandler->response($this);
  103. } else if(!empty($aHandler['service_call']) && BxDolService::isSerializedService($aHandler['service_call'])) {
  104. $aService = unserialize($aHandler['service_call']);
  105. $aParams = array($this);
  106. if(isset($aService['params']) && is_array($aService['params']))
  107. $aParams = array_merge($aParams, $aService['params']);
  108. BxDolService::call($aService['module'], $aService['method'], $aParams, isset($aService['class']) ? $aService['class'] : 'Module');
  109. }
  110. if (isset($GLOBALS['bx_profiler']) && 'bx_profiler' != $aHandler['name']) $GLOBALS['bx_profiler']->endAlert($this->sUnit, $this->sAction, $aHandler['name']);
  111. }
  112. }
  113. /**
  114. * Cache alerts and handlers.
  115. *
  116. * @return an array with all alerts and handlers.
  117. */
  118. public function getAlertsData()
  119. {
  120. $oDb = BxDolDb::getInstance();
  121. $aResult = array('alerts' => array(), 'handlers' => array());
  122. $aAlerts = $oDb->getAll("SELECT `unit`, `action`, `handler_id` FROM `sys_alerts` ORDER BY `id` ASC");
  123. foreach ($aAlerts as $aAlert)
  124. $aResult['alerts'][$aAlert['unit']][$aAlert['action']][] = $aAlert['handler_id'];
  125. $aHandlers = $oDb->getAll("SELECT `id`, `class`, `file`, `service_call`, `name` FROM `sys_alerts_handlers` ORDER BY `id` ASC");
  126. foreach ($aHandlers as $aHandler)
  127. $aResult['handlers'][$aHandler['id']] = array('class' => $aHandler['class'], 'file' => $aHandler['file'], 'service_call' => $aHandler['service_call'], 'name' => $aHandler['name']);
  128. return $aResult;
  129. }
  130. }
  131. class BxDolAlertsResponse extends BxDol
  132. {
  133. public function __construct()
  134. {
  135. parent::__construct();
  136. }
  137. public function response($oAlert) {}
  138. }
  139. /** @} */