BxDolAlerts.php 5.5 KB

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