BxAntispamModule.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  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 Antispam Antispam
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. class BxAntispamModule extends BxDolModule
  12. {
  13. private $_bLastSubmittedFormWasToxic;
  14. public function __construct(&$aModule)
  15. {
  16. parent::__construct($aModule);
  17. $this->_bLastSubmittedFormWasToxic = false;
  18. }
  19. public function actionContentChecked()
  20. {
  21. $iResult = 404;
  22. if($this->_oConfig->getAntispamOption('lm_enable') == 'on') {
  23. $oLassoModeration = bx_instance('BxAntispamLassoModeration', [], $this->getName());
  24. $iResult = $oLassoModeration->processEvent();
  25. }
  26. http_response_code($iResult);
  27. }
  28. public function serviceUpdateDisposableDomainsLists ()
  29. {
  30. $o = bx_instance('BxAntispamDisposableEmailDomains', array(), 'bx_antispam');
  31. $o->updateList('blacklist', 'https://raw.githubusercontent.com/martenson/disposable-email-domains/master/disposable_email_blocklist.conf');
  32. // TODO: uncomment after adding interface for whitelisting
  33. // $o->updateList('whitelist', 'https://raw.githubusercontent.com/martenson/disposable-email-domains/master/whitelist.conf');
  34. }
  35. public function serviceIpTable ()
  36. {
  37. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  38. $s = _t('_bx_antispam_ip_table_status', mb_strtolower($o->getIpTableConfigTitle((int)getParam('bx_antispam_ip_list_type'))));
  39. $s .= $this->_grid('bx_antispam_grid_ip_table');
  40. return $s;
  41. }
  42. public function serviceDnsblList ()
  43. {
  44. $s = _t('_bx_antispam_dnsbl_status',
  45. BxTemplFunctions::getInstance()->statusOnOff((bool)$this->_oConfig->getAntispamOption('dnsbl_enable'), true),
  46. BxTemplFunctions::getInstance()->statusOnOff((bool)$this->_oConfig->getAntispamOption('uridnsbl_enable'), true),
  47. mb_strtolower(_t('_bx_antispam_dnsbl_behaviour_login_' . $this->_oConfig->getAntispamOption('dnsbl_behaviour_login'))),
  48. mb_strtolower(_t('_bx_antispam_dnsbl_behaviour_join_' . $this->_oConfig->getAntispamOption('dnsbl_behaviour_join')))
  49. );
  50. $s .= $this->_grid('bx_antispam_grid_dnsbl');
  51. return $s;
  52. }
  53. public function serviceBlockLog ()
  54. {
  55. return $this->_grid('bx_antispam_grid_block_log');
  56. }
  57. /**
  58. * Filter undesired words
  59. *
  60. * @param $sContent content to filter
  61. * @param $sIp IP address of content poster
  62. * @return modified or the same content.
  63. */
  64. public function serviceFilterSpam ($mContent, $sIp = '')
  65. {
  66. if (defined('BX_DOL_CRON_EXECUTE') || isAdmin() || 'on' != $this->_oConfig->getAntispamOption('profanity_enable'))
  67. return $mContent;
  68. $oProfanityFilter = bx_instance('BxAntispamProfanityFilter', array(), $this->_aModule);
  69. return $oProfanityFilter->censor($mContent);
  70. }
  71. /**
  72. * Check text for spam URL.
  73. * It checks URLs found in text for DNSURI black lists (@see BxAntispamDNSURIBlacklists),
  74. *
  75. * @param $sContent content to check for spam
  76. * @return true if spam detected, false if spam isn't detected, null if detection wasn't performed.
  77. */
  78. public function serviceIsSpamUrl ($sContent)
  79. {
  80. $bRet = null;
  81. if ('on' == $this->_oConfig->getAntispamOption('uridnsbl_enable')) {
  82. $oDNSURIBlacklists = bx_instance('BxAntispamDNSURIBlacklists', array(), $this->_aModule);
  83. if ($oDNSURIBlacklists->isSpam($sContent)) {
  84. $oDNSURIBlacklists->onPositiveDetection($sContent);
  85. $bRet = true;
  86. }
  87. else {
  88. $bRet = false;
  89. }
  90. }
  91. return $bRet;
  92. }
  93. /**
  94. * Check text for spam.
  95. * First it check if IP is whitelisted(or under cron execution or user is admin) - for whitelisted IPs check for spam isn't performed,
  96. * then it checks URLs found in text for DNSURI black lists (@see BxAntispamDNSURIBlacklists),
  97. * then it checks text in Akismet service (@see BxAntispamAkismet).
  98. * It can send report if spam is found or tries to inform caller to block the content (depending on configuration).
  99. *
  100. * @param $sContent content to check for spam
  101. * @param $sIp IP address of content poster
  102. * @param $isStripSlashes slashes parameter:
  103. * BX_SLASHES_AUTO - automatically detect magic_quotes_gpc setting
  104. * BX_SLASHES_NO_ACTION - do not perform any action with slashes
  105. * @return true if spam detected and content shouln't be recorded, false if content should be processed as usual.
  106. */
  107. public function serviceIsSpam ($sContent, $sIp = '', $isStripSlashes = BX_SLASHES_AUTO)
  108. {
  109. if (defined('BX_DOL_CRON_EXECUTE') || isAdmin())
  110. return false;
  111. if ($this->serviceIsIpWhitelisted($sIp))
  112. return false;
  113. if (version_compare(phpversion(), '7.4.0', '<') && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() && $isStripSlashes == BX_SLASHES_AUTO)
  114. $sContent = stripslashes($sContent);
  115. $bRet = false;
  116. if ('on' == $this->_oConfig->getAntispamOption('uridnsbl_enable')) {
  117. $oDNSURIBlacklists = bx_instance('BxAntispamDNSURIBlacklists', array(), $this->_aModule);
  118. if ($oDNSURIBlacklists->isSpam($sContent)) {
  119. $oDNSURIBlacklists->onPositiveDetection($sContent);
  120. $bRet = true;
  121. }
  122. }
  123. if (!$bRet && 'on' == $this->_oConfig->getAntispamOption('akismet_enable')) {
  124. $oAkismet = bx_instance('BxAntispamAkismet', array(), $this->_aModule);
  125. if ($oAkismet->isSpam($sContent)) {
  126. $oAkismet->onPositiveDetection($sContent);
  127. $bRet = true;
  128. }
  129. }
  130. if ($bRet && 'on' == $this->_oConfig->getAntispamOption('antispam_report')) {
  131. $oProfile = BxDolProfile::getInstance();
  132. $aPlus = array(
  133. 'SpammerUrl' => $oProfile->getUrl(),
  134. 'SpammerNickName' => $oProfile->getDisplayName(),
  135. 'Page' => htmlspecialchars_adv($_SERVER['PHP_SELF']),
  136. 'Get' => print_r($_GET, true),
  137. 'Post' => print_r($_POST, true),
  138. 'SpamContent' => htmlspecialchars_adv($sContent),
  139. );
  140. $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate('bx_antispam_spam_report', $aPlus);
  141. if (!$aTemplate)
  142. trigger_error('Email template or translation missing: bx_antispam_spam_report', E_USER_ERROR);
  143. sendMail(getParam('site_email'), $aTemplate['Subject'], $aTemplate['Body']);
  144. }
  145. if ($bRet && 'on' == $this->_oConfig->getAntispamOption('antispam_block'))
  146. return true;
  147. return false;
  148. }
  149. /**
  150. * Check text for toxicity.
  151. * It can send report if toxic content is found or tries to inform caller to block the content (depending on configuration).
  152. *
  153. * @param $sContent content to check for spam
  154. * @param $sIp IP address of content poster
  155. * @param $isStripSlashes slashes parameter:
  156. * BX_SLASHES_AUTO - automatically detect magic_quotes_gpc setting
  157. * BX_SLASHES_NO_ACTION - do not perform any action with slashes
  158. * @return true if toxic content detected and content shouln't be recorded, false if content should be processed as usual.
  159. */
  160. public function serviceIsToxic ($sContent, $sIp = '', $isStripSlashes = BX_SLASHES_AUTO, $bSupressNotification = false)
  161. {
  162. if (defined('BX_DOL_CRON_EXECUTE') || isAdmin())
  163. return false;
  164. static $aQuickCache;
  165. $key = md5($sContent);
  166. if (isset($aQuickCache[$key]))
  167. return $aQuickCache[$key];
  168. $aQuickCache[$key] = false;
  169. if (!$this->serviceIsIpWhitelisted($sIp)) {
  170. if (version_compare(phpversion(), '7.4.0', '<') && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() && $isStripSlashes == BX_SLASHES_AUTO)
  171. $sContent = stripslashes($sContent);
  172. if ('on' == $this->_oConfig->getAntispamOption('toxicity_enable')) {
  173. $oPerspectiveAPI = bx_instance('BxAntispamPerspectiveAPI', array(), $this->_aModule);
  174. if ($oPerspectiveAPI->isToxic($sContent)) {
  175. $oPerspectiveAPI->onPositiveDetection($sContent);
  176. $aQuickCache[$key] = true;
  177. if (!$bSupressNotification) $this->serviceOnToxicContentFound($sContent);
  178. }
  179. }
  180. }
  181. return $aQuickCache[$key];
  182. }
  183. public function serviceCheckFormForToxicity(&$oForm) {
  184. $this->_bLastSubmittedFormWasToxic = false;
  185. if (!$oForm->isSubmitted() || !$oForm->isValid())
  186. return false;
  187. $sSubmitName = false;
  188. $sFormText = '';
  189. foreach ($oForm->aInputs as $k => $a) {
  190. if (isset($a['visible_for_levels']) && !BxDolForm::isVisible($a))
  191. continue;
  192. if (empty($a['name']) || 'submit' == $a['type'] || 'reset' == $a['type'] || 'button' == $a['type'] || 'value' == $a['type']) {
  193. if (isset($a['type']) && 'submit' == $a['type'])
  194. $sSubmitName = $k;
  195. continue;
  196. }
  197. if ('input_set' == $a['type'])
  198. foreach ($a as $r)
  199. if (isset($r['type']) && 'submit' == $r['type'])
  200. $sSubmitName = $k;
  201. $a['name'] = str_replace('[]', '', $a['name']);
  202. if ($a['type'] != 'textarea' && $a['type'] != 'text')
  203. continue;
  204. $val = BxDolForm::getSubmittedValue($a['name'], $oForm->aFormAttrs['method']);
  205. if (!$val)
  206. continue;
  207. $sFormText .= " ".$val; // collect all text fields into a single text
  208. }
  209. if ($this->serviceIsToxic($sFormText, '', BX_SLASHES_AUTO, true)) {
  210. $this->_bLastSubmittedFormWasToxic = true;
  211. $sActionrequired = $this->_oConfig->getAntispamOption('toxicity_action');
  212. if ($sActionrequired == 'block' || $sActionrequired == 'disapprove' && !$oForm->isStatusFieldSupported()) {
  213. $oForm->setValid(false);
  214. $this->serviceOnToxicContentFound($sFormText);
  215. if ($sSubmitName)
  216. $oForm->aInputs[$sSubmitName]['error'] = _t('_bx_antispam_form_submission_error');
  217. } elseif ($sActionrequired == 'disapprove' && $oForm->isStatusFieldSupported()) {
  218. $oForm->setForceSetToPending(true);
  219. return false;
  220. }
  221. }
  222. }
  223. public function serviceIsLastFormSubmittedToxic() {
  224. return $this->_bLastSubmittedFormWasToxic;
  225. }
  226. public function serviceSetCommentAsPending($iCmtId) {
  227. return $this->_oDb->setCommentStatus($iCmtId, BX_CMT_STATUS_PENDING);
  228. }
  229. public function serviceOnFormSubmitted($sModule, $iEntry, $sAction, &$oForm)
  230. {
  231. if ($this->_bLastSubmittedFormWasToxic) {
  232. $this->serviceOnToxicContentPosted($sModule, $iEntry);
  233. }
  234. if($this->_oConfig->getAntispamOption('lm_enable') == 'on' && (bx_srv('system', 'is_module_content', [$sModule]) || bx_srv('system', 'is_module_context', [$sModule]) || in_array($sModule, ['bx_timeline'])) && ($oModule = BxDolModule::getInstance($sModule)) !== null) {
  235. $CNF = &$oModule->_oConfig->CNF;
  236. if(($iAuthorId = bx_get_logged_profile_id()) !== false && ($oAuthor = BxDolProfile::getInstance()) !== false) {
  237. $iDataAdded = time();
  238. $sText = '';
  239. if(isset($CNF['FIELD_TEXT'], $oForm->aInputs[$CNF['FIELD_TEXT']]))
  240. $sText = $oForm->getCleanValue($CNF['FIELD_TEXT']);
  241. if(empty($sText) && isset($oForm->aInputs['text']))
  242. $sText = $oForm->getCleanValue('text');
  243. $aMedias = [
  244. 'images' => ['fields' => ['FIELD_PHOTO', 'FIELD_PICTURE', 'FIELD_COVER'], 'data' => []],
  245. 'videos' => ['fields' => ['FIELD_VIDEO'], 'data' => []]
  246. ];
  247. foreach($aMedias as $sName => $aMedia)
  248. foreach($aMedia['fields'] as $sField) {
  249. if(!isset($CNF[$sField], $oForm->aInputs[$CNF[$sField]]))
  250. continue;
  251. $oStorage = BxDolStorage::getObjectInstance($oForm->aInputs[$CNF[$sField]]['storage_object']);
  252. if(!$oStorage)
  253. continue;
  254. $aGhosts = $oStorage->getGhosts($iAuthorId, $sAction == 'insert' ? 0 : $iEntry);
  255. foreach($aGhosts as $aGhost)
  256. $aMedias[$sName]['data'][] = $oStorage->getFileUrlById($aGhost['id']);
  257. }
  258. $oLassoModeration = bx_instance('BxAntispamLassoModeration', [], $this->getName());
  259. $oLassoModeration->addContent($sModule, $iEntry, [
  260. 'author_id' => $iAuthorId,
  261. 'author_name' => $oAuthor->getDisplayName(),
  262. 'date_added' => $iDataAdded,
  263. 'text' => $sText,
  264. 'images' => $aMedias['images']['data'],
  265. 'videos' => $aMedias['videos']['data']
  266. ]);
  267. }
  268. }
  269. }
  270. public function serviceOnToxicContentFound(&$sText) {
  271. if ('on' == $this->_oConfig->getAntispamOption('toxicity_report')) {
  272. $oProfile = BxDolProfile::getInstance();
  273. if (!$oProfile) return;
  274. $aPlus = array(
  275. 'AuthorUrl' => $oProfile->getUrl(),
  276. 'AuthorNickName' => $oProfile->getDisplayName(),
  277. 'Page' => htmlspecialchars_adv($_SERVER['PHP_SELF']),
  278. 'Content' => htmlspecialchars_adv(strip_tags($sText)),
  279. );
  280. $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate('bx_antispam_toxicity_blocked_report', $aPlus);
  281. if (!$aTemplate)
  282. trigger_error('Email template or translation missing: bx_antispam_toxicity_blocked_report', E_USER_ERROR);
  283. sendMail(getParam('site_email'), $aTemplate['Subject'], $aTemplate['Body']);
  284. bx_alert('bx_antispam', 'toxic_content_found', 0, bx_get_logged_profile_id(), array(
  285. 'text' => $sText,
  286. ));
  287. }
  288. }
  289. public function serviceOnToxicContentPosted($sModule, $iContentId) {
  290. if ('on' == $this->_oConfig->getAntispamOption('toxicity_report') && $sModule) {
  291. $oModule = BxDolModule::getInstance($sModule);
  292. $CNF = &$oModule->_oConfig->CNF;
  293. $sContentUrl = isset($CNF['URI_VIEW_ENTRY']) ? bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId)) : false;
  294. $sManageContentUrl = isset($CNF['URL_MANAGE_ADMINISTRATION']) ? bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URL_MANAGE_ADMINISTRATION'])) : false;
  295. $oProfile = BxDolProfile::getInstance();
  296. if (!$oProfile) return;
  297. $aPlus = array(
  298. 'AuthorUrl' => $oProfile->getUrl(),
  299. 'AuthorNickName' => $oProfile->getDisplayName(),
  300. 'Page' => htmlspecialchars_adv($_SERVER['PHP_SELF']),
  301. 'bx_if:content_url' => [
  302. 'condition' => boolval($sContentUrl),
  303. 'content' => ['c_url' => $sContentUrl],
  304. ],
  305. 'bx_if:manage_content_url' => [
  306. 'condition' => boolval($sManageContentUrl),
  307. 'content' => ['m_url' => $sManageContentUrl],
  308. ],
  309. );
  310. $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate('bx_antispam_toxicity_posted_report', $aPlus);
  311. if (!$aTemplate)
  312. trigger_error('Email template or translation missing: bx_antispam_toxicity_posted_report', E_USER_ERROR);
  313. sendMail(getParam('site_email'), $aTemplate['Subject'], $aTemplate['Body']);
  314. bx_alert('bx_antispam', 'toxic_content_posted', $iContentId, bx_get_logged_profile_id(), array(
  315. 'module' => $sModule,
  316. 'entry_id' => $iContentId,
  317. 'entry_url' => $sContentUrl,
  318. ));
  319. }
  320. }
  321. /**
  322. * Perform complex check if user is allowed to login.
  323. * First it checks if IP is directly blocked (@see serviceIsIpBlocked),
  324. * then it checks in DNS black lists (@see serviceIsIpDnsBlacklisted).
  325. *
  326. * @param $sIp IP to check, or empty for current IP
  327. * @return empty string - if join should be allowed, error message - if join should be blocked
  328. */
  329. public function serviceCheckLogin ($sIp = '')
  330. {
  331. $bLoginBlock = ('block' == $this->_oConfig->getAntispamOption('dnsbl_behaviour_login'));
  332. $sErrorMsg = '';
  333. $sNote = $bLoginBlock ? 'login block' : 'login log';
  334. if (!$sIp)
  335. $sIp = getVisitorIP();
  336. if (!$sErrorMsg && $this->serviceIsIpBlocked($sIp))
  337. $sErrorMsg = $this->getErrorMessageIpBlocked();
  338. if (!$sErrorMsg && 'on' == $this->_oConfig->getAntispamOption('dnsbl_enable') && $this->serviceIsIpDnsBlacklisted($sIp, $sNote) && $bLoginBlock)
  339. $sErrorMsg = $this->getErrorMessageSpam();
  340. return $sErrorMsg;
  341. }
  342. /**
  343. * Perform complex check if user is allowed to join.
  344. * First it checks if IP is directly blocked (@see serviceIsIpBlocked),
  345. * then it checks in DNS black lists (@see serviceIsIpDnsBlacklisted),
  346. * then it checks in StopForumSpam service (@see BxAntispamStopForumSpam).
  347. *
  348. * @param $sCurIP IP to check, or empty for current IP
  349. * @return empty string - if join should be allowed, error message - if join should be blocked
  350. */
  351. public function serviceCheckJoin ($sEmail, &$bApproval, $sIp = '')
  352. {
  353. $bJoinBlock = ('block' == $this->_oConfig->getAntispamOption('dnsbl_behaviour_join'));
  354. $sErrorMsg = '';
  355. $sNote = $bJoinBlock ? 'join block' : 'join approval';
  356. if (!$sIp)
  357. $sIp = getVisitorIP();
  358. // check if IP is blocked
  359. if (!$sErrorMsg && $this->serviceIsIpBlocked($sIp))
  360. $sErrorMsg = $this->getErrorMessageIpBlocked();
  361. // check in DNSBL lists
  362. if (!$sErrorMsg && 'on' == $this->_oConfig->getAntispamOption('dnsbl_enable') && $this->serviceIsIpDnsBlacklisted($sIp, $sNote)) {
  363. if ('approval' == $this->_oConfig->getAntispamOption('dnsbl_behaviour_join'))
  364. $bApproval = true;
  365. else
  366. $sErrorMsg = $this->getErrorMessageSpam();
  367. }
  368. // check in StopForumSpam service
  369. if (!$sErrorMsg) {
  370. $oStopForumSpam = bx_instance('BxAntispamStopForumSpam', array(), $this->_aModule);
  371. if ($oStopForumSpam->isSpammer(array('email' => $sEmail, 'ip' => $sIp), $sNote))
  372. $sErrorMsg = $this->getErrorMessageSpam();
  373. }
  374. // check for disposable email domains
  375. if (!$sErrorMsg && 'disable' != ($sMode = $this->_oConfig->getAntispamOption('disposable_email_domains_mode'))) {
  376. $bDisposableEmailDomainsBehaviour = $this->_oConfig->getAntispamOption('disposable_email_domains_behaviour_join');
  377. $oDisposableEmailDomains = bx_instance('BxAntispamDisposableEmailDomains', array(), 'bx_antispam');
  378. if ('blacklist' == $sMode && $oDisposableEmailDomains->isBlacklisted($sEmail)) {
  379. if ('approval' == $bDisposableEmailDomainsBehaviour)
  380. $bApproval = true;
  381. else
  382. $sErrorMsg = $oDisposableEmailDomains->getErrorMessageBlacklisted();
  383. }
  384. elseif ('whitelist' == $sMode && !$oDisposableEmailDomains->isWhitelisted($sEmail)) {
  385. if ('approval' == $bDisposableEmailDomainsBehaviour)
  386. $bApproval = true;
  387. else
  388. $sErrorMsg = $oDisposableEmailDomains->getErrorMessageNotWhitelisted();
  389. }
  390. }
  391. return $sErrorMsg;
  392. }
  393. /**
  394. * Check if IP is blacklisted in some DNS chain (@see BxAntispamDNSBlacklists).
  395. *
  396. * @param $sCurIP IP to check, or empty for current IP
  397. * @param $sNote [optional] place where checking is performed, for example 'join', 'login'
  398. * @return true if IP blacklisted and not whiteloisted, or false if under cron execution or if IP isn't blacklisted
  399. */
  400. public function serviceIsIpDnsBlacklisted($sCurIP = '', $sNote = '')
  401. {
  402. if (defined('BX_DOL_CRON_EXECUTE'))
  403. return false;
  404. if (!$sCurIP)
  405. $sCurIP = getVisitorIP();
  406. if ($this->serviceIsIpWhitelisted($sCurIP))
  407. return false;
  408. $o = bx_instance('BxAntispamDNSBlacklists', array(), $this->_aModule);
  409. if (BX_DOL_DNSBL_POSITIVE == $o->dnsbl_lookup_ip(BX_DOL_DNSBL_CHAIN_SPAMMERS, $sCurIP) && BX_DOL_DNSBL_POSITIVE != $o->dnsbl_lookup_ip(BX_DOL_DNSBL_CHAIN_WHITELIST, $sCurIP)) {
  410. $o->onPositiveDetection ($sCurIP, $sNote);
  411. return true;
  412. }
  413. return false;
  414. }
  415. /**
  416. * @see BxAntispamIP::isIpWhitelisted
  417. */
  418. public function serviceIsIpWhitelisted($sIp = '')
  419. {
  420. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  421. return $o->isIpWhitelisted($sIp);
  422. }
  423. /**
  424. * @see BxAntispamIP::isIpBlocked
  425. */
  426. public function serviceIsIpBlocked($sIp = '')
  427. {
  428. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  429. return $o->isIpBlocked($sIp);
  430. }
  431. /**
  432. * @see BxAntispamIP::blockIp
  433. */
  434. public function serviceBlockIp($mixedIP, $iExpirationInSec = 86400, $sComment = '')
  435. {
  436. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  437. return $o->blockIp($mixedIP, $iExpirationInSec, $sComment);
  438. }
  439. /**
  440. * @see BxAntispamIP::pruning
  441. */
  442. public function servicePruning()
  443. {
  444. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  445. return $o->pruning();
  446. }
  447. /**
  448. * @see BxAntispamIP::pruning
  449. */
  450. public function serviceConfigValues($s)
  451. {
  452. switch ($s) {
  453. case 'ip_table':
  454. $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
  455. return $o->getIpTableConfigValues();
  456. case 'dnsbl_login':
  457. $o = bx_instance('BxAntispamDNSBlacklists', array(), $this->_aModule);
  458. return $o->getDNSBLConfigValues();
  459. case 'dnsbl_join':
  460. $o = bx_instance('BxAntispamDNSURIBlacklists', array(), $this->_aModule);
  461. return $o->getURIDNSBLConfigValues();
  462. case 'disposable_email_domains_join':
  463. $o = bx_instance('BxAntispamDisposableEmailDomains', array(), $this->_aModule);
  464. return $o->getJoinBehaviourValues();
  465. case 'disposable_email_domains_mode':
  466. $o = bx_instance('BxAntispamDisposableEmailDomains', array(), $this->_aModule);
  467. return $o->getJoinBehaviourModes();
  468. }
  469. }
  470. /**
  471. * @return array with avaliable dictionaries languages
  472. */
  473. public function serviceGetProfanityFilterDicts ()
  474. {
  475. $oProfanityFilter = bx_instance('BxAntispamProfanityFilter', array(), $this->_aModule);
  476. return $oProfanityFilter->getDicts();
  477. }
  478. /**
  479. * @return array with avaliable toxicity filter actions
  480. */
  481. public function serviceGetToxicityFilterActions ()
  482. {
  483. return [
  484. 'none' => _t('_bx_antispam_option_toxicity_filter_action_none'),
  485. 'block' => _t('_bx_antispam_option_toxicity_filter_action_block'),
  486. 'disapprove' => _t('_bx_antispam_option_toxicity_filter_action_disapprove'),
  487. ];
  488. }
  489. /**
  490. * @return array with avaliable Lasso Moderation actions
  491. */
  492. public function serviceGetLassoModerationActions ()
  493. {
  494. return [
  495. 'none' => _t('_bx_antispam_option_lasso_moderation_action_none'),
  496. 'disapprove' => _t('_bx_antispam_option_lasso_moderation_action_disapprove'),
  497. ];
  498. }
  499. public function log($mixedContents, $sSection = '', $sTitle = '')
  500. {
  501. if(is_array($mixedContents))
  502. $mixedContents = var_export($mixedContents, true);
  503. else if(is_object($mixedContents))
  504. $mixedContents = json_encode($mixedContents);
  505. if(empty($sSection))
  506. $sSection = "Core";
  507. $sTitle .= "\n";
  508. bx_log('bx_antispam', ":\n[" . $sSection . "] " . $sTitle . $mixedContents);
  509. }
  510. protected function getErrorMessageIpBlocked ()
  511. {
  512. bx_import('BxDolLanguages');
  513. return _t('_bx_antispam_ip_blocked', $this->getErrorMessageSubmitFalsePositiveReport());
  514. }
  515. protected function getErrorMessageSpam ()
  516. {
  517. bx_import('BxDolLanguages');
  518. return _t('_bx_antispam_spam_detected', $this->getErrorMessageSubmitFalsePositiveReport());
  519. }
  520. protected function getErrorMessageSubmitFalsePositiveReport ()
  521. {
  522. if (BxDolRequest::serviceExists('bx_contact', 'get_contact_page_url') && ($sUrl = BxDolService::call('bx_contact', 'get_contact_page_url')))
  523. return _t('_bx_antispam_submit_false_positive_report', $sUrl);
  524. return '';
  525. }
  526. protected function _grid ($sObjectGrid)
  527. {
  528. $oGrid = BxDolGrid::getObjectInstance($sObjectGrid);
  529. return $oGrid ? $oGrid->getCode() : '';
  530. }
  531. }
  532. /** @} */