BxNtfsTemplate.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  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 Notifications Notifications
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. require_once(BX_DIRECTORY_PATH_INC . "design.inc.php");
  12. class BxNtfsTemplate extends BxBaseModNotificationsTemplate
  13. {
  14. function __construct(&$oConfig, &$oDb)
  15. {
  16. parent::__construct($oConfig, $oDb);
  17. }
  18. public function getInclude($bIncludeCss = true, $mixedIncludeJs = false)
  19. {
  20. if($bIncludeCss)
  21. $this->getAddedCss();
  22. $sResult = '';
  23. if(is_string($mixedIncludeJs) && !empty($mixedIncludeJs)) {
  24. $this->getAddedJs();
  25. $sResult = $this->getJsCode($mixedIncludeJs);
  26. }
  27. return $sResult;
  28. }
  29. public function getViewBlock($aParams)
  30. {
  31. return $this->parseHtmlByName('block_view.html', array(
  32. 'html_id_view_block' => $this->_oConfig->getHtmlIds('view', 'block'),
  33. 'html_id_events' => $this->_oConfig->getHtmlIds('view', 'events'),
  34. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  35. 'content' => $this->getPosts($aParams),
  36. 'js_content' => $this->getJsCode('view', array(
  37. 'oRequestParams' => array(
  38. 'type' => $aParams['type'],
  39. 'owner_id' => $aParams['owner_id'],
  40. 'start' => $aParams['start'],
  41. 'per_page' => $aParams['per_page'],
  42. 'modules' => $aParams['modules']
  43. )
  44. ))
  45. ));
  46. }
  47. public function getSettingsBlock($sDeliveryType, $aParams = array())
  48. {
  49. $CNF = &$this->_oConfig->CNF;
  50. $iUserId = !empty($aParams['user_id']) ? (int)$aParams['user_id'] : bx_get_logged_profile_id();
  51. $sGrid = !empty($aParams['grid']) ? $aParams['grid'] : $CNF['OBJECT_GRID_SETTINGS_COMMON'];
  52. $oTemplate = !empty($aParams['template']) ? $aParams['template'] : $this;
  53. $oGrid = BxDolGrid::getObjectInstance($sGrid, $oTemplate);
  54. if(!$oGrid)
  55. return '';
  56. $oGrid->setDeliveryType($sDeliveryType);
  57. if(method_exists($oGrid, 'setUserId'))
  58. $oGrid->setUserId($iUserId);
  59. return !$this->_bIsApi ? $oGrid->getCode() : [
  60. bx_api_get_block('notifications_settings', $oGrid->getCodeApi(true), ['ext' => ['request_url' => '/api.php?r=' . $this->_oConfig->getName() . '/enable_setting/&params[]=']])
  61. ];
  62. }
  63. public function getPosts($aParams)
  64. {
  65. $sJsObject = $this->_oConfig->getJsObject('view');
  66. $aParamsDb = $aParams;
  67. $aParamsDb['per_page'] = 3 * $aParamsDb['per_page'];
  68. $aEvents = $this->_oDb->getEvents($aParamsDb);
  69. if(empty($aEvents))
  70. return bx_is_api() ? [] : $this->getEmpty();
  71. if($this->_oConfig->isEventsGrouped())
  72. $this->_oModule->groupEvents($aEvents);
  73. $aTmplVarsEvents = array();
  74. foreach($aEvents as $aEvent) {
  75. $sEvent = $this->getPost($aEvent, $aParams);
  76. if(empty($sEvent))
  77. continue;
  78. if($this->_bIsApi)
  79. $aTmplVarsEvents[] = $sEvent;
  80. else
  81. $aTmplVarsEvents[] = ['event' => $sEvent];
  82. if(count($aTmplVarsEvents) >= ($aParams['per_page'] + 1))
  83. break;
  84. }
  85. if($this->_bIsApi)
  86. return $aTmplVarsEvents;
  87. $oPaginate = new BxTemplPaginate([
  88. 'start' => $aParams['start'],
  89. 'per_page' => $aParams['per_page'],
  90. 'page_url' => $this->_oConfig->getViewUrl(),
  91. 'on_change_page' => $sJsObject . ".changePage(this, {start}, {per_page})"
  92. ]);
  93. $oPaginate->setNumFromDataArray($aTmplVarsEvents);
  94. return $this->parseHtmlByName('events.html', [
  95. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  96. 'bx_repeat:events' => $aTmplVarsEvents,
  97. 'paginate' => $oPaginate->getSimplePaginate()
  98. ]);
  99. }
  100. /**
  101. * Enter description here ...
  102. * @example Available keys are:
  103. * 1. owner_name and owner_link
  104. * 2. entry_caption and entry_url
  105. * 3. subentry_url and subentry_sample
  106. *
  107. */
  108. public function getPost(&$aEvent, $aBrowseParams = array())
  109. {
  110. $oModule = $this->getModule();
  111. if(!empty($aEvent['content']) && is_string($aEvent['content']))
  112. $aEvent['content'] = unserialize($aEvent['content']);
  113. if((int)$aEvent['processed'] == 0)
  114. $this->_processContent($aEvent);
  115. if((int)$aEvent['processed'] == 0 || empty($aEvent['content']))
  116. return '';
  117. $sParamCheck = 'perform_privacy_check';
  118. if(!isset($aBrowseParams[$sParamCheck]) || $aBrowseParams[$sParamCheck] === true) {
  119. $sParamCheckFor = 'perform_privacy_check_for';
  120. $iViewerId = !empty($aBrowseParams[$sParamCheckFor]) ? (int)$aBrowseParams[$sParamCheckFor] : 0;
  121. $oPrivacyInt = BxDolPrivacy::getObjectInstance($this->_oConfig->getObject('privacy_view'));
  122. if(!$oPrivacyInt->check($aEvent['id'], $iViewerId))
  123. return '';
  124. $oPrivacyExt = $this->_oConfig->getPrivacyObject($aEvent['type'] . '_' . $aEvent['action']);
  125. if($oPrivacyExt !== false && !$oPrivacyExt->check($aEvent['id'], $iViewerId))
  126. return '';
  127. $sSrvModule = $this->_oConfig->getContentModule($aEvent);
  128. $sSrvMethod = 'check_allowed_with_content_for_profile';
  129. if($sSrvModule && bx_is_srv($sSrvModule, $sSrvMethod) && bx_srv($sSrvModule, $sSrvMethod, ['view', $this->_oConfig->getContentObjectId($aEvent), $iViewerId]) !== CHECK_ACTION_RESULT_ALLOWED)
  130. return '';
  131. }
  132. $bShowRealProfile = !isset($aBrowseParams['show_real_profile']) || $aBrowseParams['show_real_profile'] === true;
  133. $oAuthor = $oModule->getObjectUser($aEvent['author_id'] ?? 0);
  134. if(!$bShowRealProfile && $oAuthor instanceof BxDolProfileAnonymous)
  135. $oAuthor->setShowRealProfile($bShowRealProfile);
  136. $aEvent['content']['author_name'] = strmaxtextlen($oAuthor->getDisplayName(), $this->_oConfig->getOwnerNameMaxLen());
  137. $aEvent['content']['author_link'] = $oAuthor->getUrl();
  138. $aEvent['content']['author_icon'] = $oAuthor->getThumb();
  139. $oOwner = $oModule->getObjectUser($aEvent['owner_id']);
  140. if(!$bShowRealProfile && $oOwner instanceof BxDolProfileAnonymous)
  141. $oOwner->setShowRealProfile($bShowRealProfile);
  142. $aEvent['content']['owner_name'] = strmaxtextlen($oOwner->getDisplayName(), $this->_oConfig->getOwnerNameMaxLen());
  143. $aEvent['content']['owner_link'] = $oOwner->getUrl();
  144. $aEvent['content']['owner_icon'] = $oOwner->getThumb();
  145. if(!empty($aEvent['content']['entry_caption'])) {
  146. $sEntryCaption = bx_process_output($aEvent['content']['entry_caption'], BX_DATA_TEXT);
  147. if(get_mb_substr($sEntryCaption, 0, 1) == '_')
  148. $sEntryCaption = _t($sEntryCaption);
  149. $aEvent['content']['entry_caption'] = strmaxtextlen($sEntryCaption, $this->_oConfig->getContentMaxLen());
  150. }
  151. $iObjectOwner = (int)$aEvent['object_owner_id'];
  152. if(empty($iObjectOwner) && !empty($aEvent['content']['entry_author']))
  153. $iObjectOwner = (int)$aEvent['content']['entry_author'];
  154. $oObjectOwner = $oModule->getObjectUser($iObjectOwner);
  155. if($oObjectOwner) {
  156. if(!$bShowRealProfile && $oObjectOwner instanceof BxDolProfileAnonymous)
  157. $oObjectOwner->setShowRealProfile($bShowRealProfile);
  158. $aEvent['content']['object_owner_name'] = strmaxtextlen($oObjectOwner->getDisplayName(), $this->_oConfig->getOwnerNameMaxLen());
  159. $aEvent['content']['object_owner_link'] = $oObjectOwner->getUrl();
  160. $aEvent['content']['object_owner_icon'] = $oObjectOwner->getThumb();
  161. }
  162. foreach($aEvent['content'] as $sKey => $sValue) {
  163. if(!is_string($sValue) || substr($sValue, 0, 1) != '_')
  164. continue;
  165. $aCallParams = array($sValue);
  166. $sKeyParams = $sKey . '_params';
  167. if(isset($aEvent['content'][$sKeyParams]) && is_array($aEvent['content'][$sKeyParams])) {
  168. foreach($aEvent['content'][$sKeyParams] as $iParamIndex => $sParamValue)
  169. if(is_string($sParamValue) && substr($sParamValue, 0, 1) == '_')
  170. $aEvent['content'][$sKeyParams][$iParamIndex] = _t($sParamValue);
  171. $aCallParams = array_merge($aCallParams, $aEvent['content'][$sKeyParams]);
  172. unset($aEvent['content'][$sKeyParams]);
  173. }
  174. $aEvent['content'][$sKey] = call_user_func_array('_t', $aCallParams);
  175. }
  176. $sAuthorUnit = '';
  177. if(($o = !($oAuthor instanceof BxDolProfileUndefined) ? $oAuthor : $oOwner) !== false)
  178. $sAuthorUnit = $o->getUnit(0, ['template' => 'unit_wo_info_links']);
  179. $bEventParsed = false;
  180. $bEventCanceled = false;
  181. /**
  182. * @hooks
  183. * @hookdef hook-bx_notifications-get_notification 'bx_notifications', 'get_notification' - hook to override notification or even cancel it
  184. * - $unit_name - equals `bx_notifications`
  185. * - $action - equals `get_notification`
  186. * - $object_id - not used
  187. * - $sender_id - not used
  188. * - $extra_params - array of additional params with the following array keys:
  189. * - `browse_params` - [array] browse params array as key&value pairs
  190. * - `event` - [array] by ref, event data array, can be overridden in hook processing
  191. * - `event_parsed` - [boolean] by ref, if event was already parsed (ready to display), can be overridden in hook processing
  192. * - `event_canceled` - [boolean] by ref, if event was canceled, can be overridden in hook processing
  193. * - `owner` - [object] by ref, an instance of owner profile, @see BxDolProfile, can be overridden in hook processing
  194. * - `owner_unit` - [string] by ref, profile unit HTML code, can be overridden in hook processing
  195. * @hook @ref hook-bx_notifications-get_notification
  196. */
  197. bx_alert($this->_oConfig->getName(), 'get_notification', 0, 0, [
  198. 'browse_params' => $aBrowseParams,
  199. 'event' => &$aEvent,
  200. 'event_parsed' => &$bEventParsed,
  201. 'event_canceled' => &$bEventCanceled,
  202. 'author' => &$oAuthor,
  203. 'owner' => &$oOwner,
  204. 'owner_unit' => &$sAuthorUnit,
  205. 'event_ref' => &$aEvent,
  206. 'event_parsed_ref' => &$bEventParsed,
  207. 'event_canceled_ref' => &$bEventCanceled,
  208. 'author_ref' => &$oAuthor,
  209. 'owner_ref' => &$oOwner,
  210. 'owner_unit_ref' => &$sAuthorUnit,
  211. ]);
  212. if($bEventCanceled)
  213. return '';
  214. if(($sGroupedByMac = $aEvent['grouped_by_mac'] ?? false) && strpos($sGroupedByMac, ',') !== false) {
  215. $aGroupedByMac = explode(',', $sGroupedByMac);
  216. $sContentParsed = '';
  217. foreach($aGroupedByMac as $iSubEventId) {
  218. $aSubEvent = $this->_oDb->getEntriesBy(['type' => 'id', 'id' => $iSubEventId]);
  219. if(!$aSubEvent || !is_array($aSubEvent))
  220. continue;
  221. if($sContentParsed && ($sK = 'content') && ($sEc = $aSubEvent[$sK] ?? '') && is_string($sEc)) {
  222. $aSubEvent[$sK] = unserialize($sEc);
  223. $aSubEvent[$sK]['author_name_wrapped'] = _t('_bx_ntfs_txt_and');
  224. }
  225. $this->getPost($aSubEvent, $aBrowseParams);
  226. if(($sCp = $aSubEvent['content_parsed'] ?? false))
  227. $sContentParsed .= ' ' . $sCp;
  228. }
  229. if($sContentParsed) {
  230. $aEvent['content_parsed'] = $sContentParsed;
  231. $bEventParsed = true;
  232. }
  233. }
  234. if(!$bEventParsed) {
  235. $mLk = '';
  236. if(!empty($aEvent['content']['lang_key'])) {
  237. $mLk = $aEvent['content']['lang_key'];
  238. if(!is_string($mLk) && !(is_array($mLk) && isset($mLk['site'], $mLk['email'], $mLk['push'])))
  239. $mLk = '';
  240. }
  241. if(empty($mLk))
  242. $mLk = $this->_getContentLangKey($aEvent);
  243. if(is_array($mLk))
  244. foreach($mLk as $sDeliveryType => $sLangKey)
  245. $aEvent['content_parsed'][$sDeliveryType] = $this->_parseContentLangKey($sLangKey, $aEvent);
  246. else
  247. $aEvent['content_parsed'] = $this->_parseContentLangKey($mLk, $aEvent);
  248. }
  249. // returns parsed content for React Jot
  250. if(isset($aBrowseParams['return_parsed_content']))
  251. return $aEvent;
  252. $bClickedIndicator = $this->_oConfig->isClickedIndicator();
  253. $sJsObject = $this->_oConfig->getJsObject('view');
  254. if($this->_bIsApi) {
  255. $aEvent['author_data'] = BxDolProfile::getData($aEvent['author_id']);
  256. $aLinks = [
  257. 'author_link' => $aEvent['content']['author_link'],
  258. 'owner_link' => $aEvent['content']['owner_link'],
  259. 'object_owner_link' => $aEvent['content']['object_owner_link']
  260. ];
  261. foreach(['entry_url', 'entry_url_api', 'subentry_url', 'subentry_url_api'] as $sKey)
  262. if(!empty($aEvent['content'][$sKey]))
  263. $aLinks[$sKey] = $this->_getLink($aEvent['content'][$sKey]);
  264. array_walk($aLinks, function(&$sValue, $sKey) {
  265. $sValue = bx_api_get_relative_url($sValue);
  266. });
  267. $aEvent['module'] = $aEvent['type'];
  268. if(!$this->_oDb->isModuleByName($aEvent['module'])) {
  269. if(!isset($aEvent['content']['module'])) {
  270. if(($s = $aEvent['source'] ?: '') || ($s = $aEvent['type']))
  271. $aEvent['module'] = substr($s, 0, strrpos($s, '_'));
  272. }
  273. else
  274. $aEvent['module'] = $aEvent['content']['module'];
  275. }
  276. $aEvent['content'] = array_merge($aEvent['content'], $aLinks);
  277. $aEvent['content'] = array_intersect_key($aEvent['content'], array_flip([
  278. 'entry_url', 'entry_url_api', 'subentry_url', 'subentry_url_api'
  279. ]));
  280. if(($sKey = 'content_parsed') && is_array($aEvent[$sKey])) {
  281. foreach($aEvent[$sKey] as $sDeliveryType => $sContentParsed)
  282. $aEvent[$sKey][$sDeliveryType] = html_entity_decode($sContentParsed);
  283. }
  284. else
  285. $aEvent[$sKey] = html_entity_decode($aEvent[$sKey]);
  286. return array_intersect_key($aEvent, array_flip([
  287. 'id', 'author_id', 'author_data', 'owner_id', 'module', 'type', 'content', 'content_parsed', 'date'
  288. ]));
  289. }
  290. return $this->parseHtmlByName('event.html', [
  291. 'html_id' => $this->_oConfig->getHtmlIds('view', 'event') . $aEvent['id'],
  292. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  293. 'js_object' => $sJsObject,
  294. 'class' => !empty($aBrowseParams['last_read']) && $aEvent['id'] > $aBrowseParams['last_read'] ? ' bx-def-color-bg-box-active' : '',
  295. 'id' => $aEvent['id'],
  296. 'author_unit' => $sAuthorUnit,
  297. 'link' => $this->_getContentLink($aEvent),
  298. 'content' => is_array($aEvent['content_parsed']) && isset($aEvent['content_parsed']['site']) ? $aEvent['content_parsed']['site'] : $aEvent['content_parsed'],
  299. 'date' => bx_time_js($aEvent['date']),
  300. 'bx_if:show_onclick' => [
  301. 'condition' => $bClickedIndicator,
  302. 'content' => [
  303. 'js_object' => $sJsObject,
  304. 'id' => $aEvent['id']
  305. ]
  306. ],
  307. 'bx_if:show_clicked_indicator' => [
  308. 'condition' => $bClickedIndicator && (!isset($aEvent['clicked']) || (int)$aEvent['clicked'] == 0),
  309. 'content' => []
  310. ],
  311. ]);
  312. }
  313. public function getNotificationEmail($iRecipient, &$aEvent)
  314. {
  315. $aContent = &$aEvent['content'];
  316. $sIconUrl = ($_sIconUrl = $aContent['author_icon'] ?? false) || ($_sIconUrl = $aContent['owner_icon'] ?? false) ? $_sIconUrl : $this->getIconUrl('std-icon.svg');
  317. $sContentUrl = bx_absolute_url($this->_getContentLink($aEvent, getParam('sys_api_url_root_email') != ''));
  318. $sContent = is_array($aEvent['content_parsed']) && isset($aEvent['content_parsed']['email']) ? $aEvent['content_parsed']['email'] : $aEvent['content_parsed'];
  319. $sSummary = (($sK = 'subentry_summary') && ($sV = $aContent[$sK] ?? false)) || (($sK = 'entry_summary') && ($sV = $aContent[$sK] ?? false)) ? $sV : '';
  320. $sDate = bx_process_output($aEvent['date'], BX_DATA_DATE_TS);
  321. $aEtemplate = $this->_oDb->getEtemplates([
  322. 'sample' => 'type_action',
  323. 'type' => $aEvent['type'],
  324. 'action' => $aEvent['action'],
  325. 'active' => 1
  326. ]);
  327. $sSubject = $sBody = '';
  328. if(!empty($aEtemplate) && is_array($aEtemplate)) {
  329. $aEtParams = array_diff_key($aContent, array_flip(['lang_key', 'settings']));
  330. $aEtParams = array_merge($aEtParams, [
  331. 'icon_url' => $sIconUrl,
  332. 'content_url' => $sContentUrl,
  333. 'content' => $sContent,
  334. 'summary' => $sSummary,
  335. 'date' => $sDate
  336. ]);
  337. $sSubject = bx_replace_markers($aEtemplate['subject'], $aEtParams);
  338. $sBody = bx_replace_markers($aEtemplate['body'], $aEtParams);
  339. }
  340. else {
  341. $sSubject = $sContent;
  342. $sBody = $this->parseHtmlByName('et_new_event.html', [
  343. 'icon_url' => $sIconUrl,
  344. 'content_url' => $sContentUrl,
  345. 'content' => $sContent,
  346. 'date' => $sDate,
  347. 'bx_if:show_summary' => [
  348. 'condition' => !empty($sSummary),
  349. 'content' => [
  350. 'summary' => $sSummary
  351. ]
  352. ]
  353. ]);
  354. }
  355. if(($iEmailSubjectMaxLen = $this->_oConfig->getEmailSubjectMaxLen()) !== 0)
  356. $sSubject = strmaxtextlen($sSubject, $iEmailSubjectMaxLen);
  357. else
  358. $sSubject = trim(strip_tags($sSubject));
  359. return [
  360. 'subject' => $sSubject,
  361. 'content' => $sBody,
  362. 'settings' => !empty($aContent['settings']['email']) ? $aContent['settings']['email'] : []
  363. ];
  364. }
  365. public function getNotificationPush($iRecipient, &$aEvent)
  366. {
  367. $sMessage = is_array($aEvent['content_parsed']) && isset($aEvent['content_parsed']['push']) ? $aEvent['content_parsed']['push'] : $aEvent['content_parsed'];
  368. $sMessage = preg_replace('/<\/?[a-zA-Z0-9=\'":;\(\)\s_-]+>/i', ($sChar = getParam("bx_ntfs_option_tag_to_char_push")) !== false ? $sChar : '"', $sMessage);
  369. if($sMessage)
  370. $sMessage = BxTemplFunctions::getInstance()->getStringWithLimitedLength(html_entity_decode($sMessage), $this->_oConfig->getPushMaxLen());
  371. if(empty($sMessage))
  372. return false;
  373. $aContent = &$aEvent['content'];
  374. return [
  375. 'content' => [
  376. 'url' => bx_absolute_url($this->_getContentLink($aEvent, getParam('sys_api_url_root_push') != '')),
  377. 'message' => $sMessage,
  378. 'icon' => !empty($aContent['owner_icon']) ? $aContent['owner_icon'] : ''
  379. ],
  380. 'settings' => !empty($aContent['settings']['push']) ? $aContent['settings']['push'] : []
  381. ];
  382. }
  383. public function getEmpty($bVisible = true)
  384. {
  385. return $this->parseHtmlByName('empty.html', array(
  386. 'style_prefix' => $this->_oConfig->getPrefix('style'),
  387. 'visible' => $bVisible ? 'block' : 'none',
  388. 'content' => MsgBox(_t('_bx_ntfs_txt_msg_no_results'))
  389. ));
  390. }
  391. public function getSelectActions($aActions)
  392. {
  393. $aTmplVarsActions = [
  394. ['value' => '', 'title' => _t('_sys_please_select')]
  395. ];
  396. foreach($aActions as $sAction)
  397. $aTmplVarsActions[] = ['value' => $sAction, 'title' => $this->getActionTitle($sAction)];
  398. return $this->parseHtmlByName('field_actions.html', [
  399. 'bx_repeat:actions' => $aTmplVarsActions
  400. ]);
  401. }
  402. public function getTypeTitle($sType)
  403. {
  404. $sResult = '';
  405. if(($sKey = '_bx_ntfs_alert_module_' . $sType) && ($_sKey = _t($sKey)) && strcmp($sKey, $_sKey) != 0)
  406. $sResult = $_sKey;
  407. else if(($sKey = '_' . $sType) && ($_sKey = _t($sKey)) && strcmp($sKey, $_sKey) != 0)
  408. $sResult = $_sKey;
  409. else if(($aModule = $this->_oDb->getModuleByName($sType)) && is_array($aModule) && ($_sKey = $aModule['title'] ?? false))
  410. $sResult = $_sKey;
  411. else
  412. $sResult = $sType;
  413. return $sResult;
  414. }
  415. public function getActionTitle($sAction)
  416. {
  417. $sResult = '';
  418. if(($sKey = '_bx_ntfs_alert_action_' . $sAction) && ($_sKey = _t($sKey)) && strcmp($sKey, $_sKey) != 0)
  419. $sResult = $_sKey;
  420. else if(($sKey .= '_personal') && ($_sKey = _t($sKey)) && strcmp($sKey, $_sKey) != 0)
  421. $sResult = $_sKey;
  422. else
  423. $sResult = $sAction;
  424. return $sResult;
  425. }
  426. protected function _processContent(&$aEvent)
  427. {
  428. $aContent = $this->_getContent($aEvent);
  429. if(empty($aContent) || !is_array($aContent))
  430. return;
  431. /**
  432. * @hooks
  433. * @hookdef hook-bx_notifications-get_content 'bx_notifications', 'get_content' - hook to override notification content
  434. * - $unit_name - equals `bx_notifications`
  435. * - $action - equals `get_content`
  436. * - $object_id - not used
  437. * - $sender_id - not used
  438. * - $extra_params - array of additional params with the following array keys:
  439. * - `event` - [array] by ref, event data array, can be overridden in hook processing
  440. * - `override_result` - [array] by ref, event content array, can be overridden in hook processing
  441. * @hook @ref hook-bx_notifications-get_content
  442. */
  443. bx_alert($this->_oConfig->getName(), 'get_content', 0, 0, [
  444. 'event' => $aEvent,
  445. 'override_result' => &$aContent
  446. ]);
  447. $aSet = array();
  448. if(!empty($aContent['entry_author'])) {
  449. $aSet['object_owner_id'] = (int)$aContent['entry_author'];
  450. unset($aContent['entry_author']);
  451. }
  452. if(!empty($aContent['entry_privacy'])) {
  453. $aSet['allow_view_event_to'] = $aContent['entry_privacy'];
  454. $aEvent['allow_view_event_to'] = $aContent['entry_privacy'];
  455. unset($aContent['entry_privacy']);
  456. }
  457. foreach(['entry_summary', 'subentry_summary'] as $sKey) {
  458. if(empty($aContent[$sKey]))
  459. continue;
  460. $sSummary = nl2br(strip_tags($aContent[$sKey]));
  461. $aContent[$sKey] = strmaxtextlen($sSummary, $this->_oConfig->getSummaryMaxLen());
  462. }
  463. if(!empty($aEvent['content'])) {
  464. if(is_string($aEvent['content']))
  465. $aEvent['content'] = unserialize($aEvent['content']);
  466. if(is_array($aEvent['content']))
  467. $aEvent['content'] = array_merge($aEvent['content'], $aContent);
  468. }
  469. else
  470. $aEvent['content'] = $aContent;
  471. $aEvent['processed'] = 1;
  472. $aSet = array_merge($aSet, array(
  473. 'content' => serialize($aEvent['content']),
  474. 'processed' => 1
  475. ));
  476. $this->_oDb->updateEvent($aSet, array('id' => $aEvent['id']));
  477. return;
  478. }
  479. protected function _getContent(&$aEvent)
  480. {
  481. $sHandler = $aEvent['type'] . '_' . $aEvent['action'];
  482. if(!$this->_oConfig->isHandler($sHandler))
  483. return array();
  484. $aHandler = $this->_oConfig->getHandlers($sHandler);
  485. if(!empty($aHandler['module_name']) && !empty($aHandler['module_class']) && !empty($aHandler['module_method']))
  486. return BxDolService::call($aHandler['module_name'], $aHandler['module_method'], array($aEvent), $aHandler['module_class']);
  487. $sMethod = 'display' . bx_gen_method_name($aHandler['alert_unit'] . '_' . $aHandler['alert_action']);
  488. if(!method_exists($this, $sMethod))
  489. return array();
  490. return $this->$sMethod($aEvent);
  491. }
  492. protected function _getContentLangKey(&$aEvent)
  493. {
  494. $bInContext = $this->_isInContext($aEvent);
  495. if(!empty($aEvent['subobject_id']))
  496. return '_bx_ntfs_txt_subobject_added' . ($bInContext ? '_in_context' : '');
  497. $sKey = '';
  498. switch($aEvent['action']) {
  499. case 'pending_approval':
  500. $sKey = '_bx_ntfs_txt_object_pending_approval';
  501. break;
  502. case 'reported_content':
  503. $sKey = '_bx_ntfs_txt_object_reported_content';
  504. break;
  505. case 'publish_failed':
  506. $sKey = '_bx_ntfs_txt_object_publish_failed';
  507. break;
  508. case 'publish_succeeded':
  509. $sKey = '_bx_ntfs_txt_object_publish_succeeded';
  510. break;
  511. default:
  512. $sKey = '_bx_ntfs_txt_object_' . $aEvent['action'] . ($bInContext ? '_in_context' : '');
  513. }
  514. return $sKey;
  515. }
  516. protected function _parseContentLangKey($sLangKey, &$aEvent)
  517. {
  518. $aMarkers = array_diff_key($aEvent['content'], array_flip([
  519. 'lang_key', 'settings'
  520. ]));
  521. $aPreparsed = [];
  522. if(($sK = 'author_name_wrapped') && !isset($aMarkers[$sK]))
  523. $aPreparsed[$sK] = _t('_bx_ntfs_txt_author_name_wrapped');
  524. if(($sK = 'owner_name_wrapped') && !isset($aMarkers[$sK]))
  525. $aPreparsed[$sK] = _t('_bx_ntfs_txt_owner_name_wrapped');
  526. if($aPreparsed)
  527. $aMarkers = array_merge($aMarkers, bx_replace_markers($aPreparsed, $aMarkers));
  528. return bx_replace_markers(_t($sLangKey), $aMarkers);
  529. }
  530. protected function _getContentLink($aEvent, $bForApi = false)
  531. {
  532. $sLink = $aEvent['content']['entry_url' . ($bForApi ? '_api' : '')] ?? $aEvent['content']['entry_url'];
  533. if(!empty($aEvent['subobject_id']) && !empty($aEvent['content']['subentry_url']))
  534. $sLink = $aEvent['content']['subentry_url' . ($bForApi ? '_api' : '')] ?? $aEvent['content']['subentry_url'];
  535. return $this->_getLink($sLink);
  536. }
  537. protected function _getLink($sLink)
  538. {
  539. return bx_replace_markers($sLink, [
  540. 'bx_url_root' => BX_DOL_URL_ROOT
  541. ]);
  542. }
  543. protected function _isInContext(&$aEvent)
  544. {
  545. return (int)$aEvent['object_privacy_view'] < 0;
  546. }
  547. }
  548. /** @} */