PageRenderTime 53ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/antispam/filters/class.dc.filter.words.php

https://bitbucket.org/dotclear/dotclear/
PHP | 369 lines | 311 code | 41 blank | 17 comment | 36 complexity | 086d1428de4007817b92b67cc2448858 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, Apache-2.0
  1. <?php
  2. # -- BEGIN LICENSE BLOCK ---------------------------------------
  3. #
  4. # This file is part of Antispam, a plugin for Dotclear 2.
  5. #
  6. # Copyright (c) 2003-2013 Olivier Meunier & Association Dotclear
  7. # Licensed under the GPL version 2.0 license.
  8. # See LICENSE file or
  9. # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  10. #
  11. # -- END LICENSE BLOCK -----------------------------------------
  12. if (!defined('DC_RC_PATH')) { return; }
  13. class dcFilterWords extends dcSpamFilter
  14. {
  15. public $has_gui = true;
  16. public $name = 'Bad Words';
  17. public $help = 'words-filter';
  18. private $con;
  19. private $table;
  20. public function __construct($core)
  21. {
  22. parent::__construct($core);
  23. $this->con =& $core->con;
  24. $this->table = $core->prefix.'spamrule';
  25. }
  26. protected function setInfo()
  27. {
  28. $this->description = __('Words Blacklist');
  29. }
  30. public function getStatusMessage($status,$comment_id)
  31. {
  32. return sprintf(__('Filtered by %1$s with word %2$s.'),$this->guiLink(),'<em>'.$status.'</em>');
  33. }
  34. public function isSpam($type,$author,$email,$site,$ip,$content,$post_id,&$status)
  35. {
  36. $str = $author.' '.$email.' '.$site.' '.$content;
  37. $rs = $this->getRules();
  38. while ($rs->fetch())
  39. {
  40. $word = $rs->rule_content;
  41. if (substr($word,0,1) == '/' && substr($word,-1,1) == '/') {
  42. $reg = substr(substr($word,1),0,-1);
  43. } else {
  44. $reg = preg_quote($word, '/');
  45. $reg = '(^|\s+|>|<)'.$reg.'(>|<|\s+|\.|$)';
  46. }
  47. if (preg_match('/'.$reg.'/msiu',$str)) {
  48. $status = $word;
  49. return true;
  50. }
  51. }
  52. }
  53. public function gui($url)
  54. {
  55. $core =& $this->core;
  56. # Create list
  57. if (!empty($_POST['createlist']))
  58. {
  59. try {
  60. $this->defaultWordsList();
  61. dcPage::addSuccessNotice(__('Words have been successfully added.'));
  62. http::redirect($url);
  63. } catch (Exception $e) {
  64. $core->error->add($e->getMessage());
  65. }
  66. }
  67. # Adding a word
  68. if (!empty($_POST['swa']))
  69. {
  70. $globalsw = !empty($_POST['globalsw']) && $core->auth->isSuperAdmin();
  71. try {
  72. $this->addRule($_POST['swa'],$globalsw);
  73. dcPage::addSuccessNotice(__('Word has been successfully added.'));
  74. http::redirect($url);
  75. } catch (Exception $e) {
  76. $core->error->add($e->getMessage());
  77. }
  78. }
  79. # Removing spamwords
  80. if (!empty($_POST['swd']) && is_array($_POST['swd']))
  81. {
  82. try {
  83. $this->removeRule($_POST['swd']);
  84. dcPage::addSuccessNotice(__('Words have been successfully removed.'));
  85. http::redirect($url);
  86. } catch (Exception $e) {
  87. $core->error->add($e->getMessage());
  88. }
  89. }
  90. /* DISPLAY
  91. ---------------------------------------------- */
  92. $res = dcPage::notices();
  93. $res .=
  94. '<form action="'.html::escapeURL($url).'" method="post" class="fieldset">'.
  95. '<p><label class="classic" for="swa">'.__('Add a word ').'</label> '.form::field('swa',20,128);
  96. if ($core->auth->isSuperAdmin()) {
  97. $res .= '<label class="classic" for="globalsw">'.form::checkbox('globalsw',1).
  98. __('Global word (used for all blogs)').'</label> ';
  99. }
  100. $res .=
  101. $core->formNonce().
  102. '</p>'.
  103. '<p><input type="submit" value="'.__('Add').'"/></p>'.
  104. '</form>';
  105. $rs = $this->getRules();
  106. if ($rs->isEmpty())
  107. {
  108. $res .= '<p><strong>'.__('No word in list.').'</strong></p>';
  109. }
  110. else
  111. {
  112. $res .=
  113. '<form action="'.html::escapeURL($url).'" method="post" class="fieldset">'.
  114. '<h3>' . __('List of bad words') . '</h3>'.
  115. '<div class="antispam">';
  116. $res_global = '';
  117. $res_local = '';
  118. while ($rs->fetch())
  119. {
  120. $disabled_word = false;
  121. $p_style = '';
  122. if (!$rs->blog_id) {
  123. $disabled_word = !$core->auth->isSuperAdmin();
  124. $p_style .= ' global';
  125. }
  126. $item = '<p class="'.$p_style.'"><label class="classic" for="word-'.$rs->rule_id.'">'.
  127. form::checkbox(array('swd[]', 'word-'.$rs->rule_id),$rs->rule_id,false,'','',$disabled_word).' '.
  128. html::escapeHTML($rs->rule_content).
  129. '</label></p>';
  130. if ($rs->blog_id) {
  131. // local list
  132. if ($res_local == '') {
  133. $res_local = '<h4>'.__('Local words (used only for this blog)').'</h4>';
  134. }
  135. $res_local .= $item;
  136. } else {
  137. // global list
  138. if ($res_global == '') {
  139. $res_global = '<h4>'.__('Global words (used for all blogs)').'</h4>';
  140. }
  141. $res_global .= $item;
  142. }
  143. }
  144. $res .= '<div class="local">'.$res_local.'</div>';
  145. $res .= '<div class="global">'.$res_global.'</div>';
  146. $res .=
  147. '</div>'.
  148. '<p>'.form::hidden(array('spamwords'),1).
  149. $core->formNonce().
  150. '<input class="submit delete" type="submit" value="' . __('Delete selected words') . '"/></p>'.
  151. '</form>';
  152. }
  153. if ($core->auth->isSuperAdmin())
  154. {
  155. $res .=
  156. '<form action="'.html::escapeURL($url).'" method="post">'.
  157. '<p><input type="submit" value="'.__('Create default wordlist').'" />'.
  158. form::hidden(array('spamwords'),1).
  159. form::hidden(array('createlist'),1).
  160. $core->formNonce().'</p>'.
  161. '</form>';
  162. }
  163. return $res;
  164. }
  165. private function getRules()
  166. {
  167. $strReq = 'SELECT rule_id, blog_id, rule_content '.
  168. 'FROM '.$this->table.' '.
  169. "WHERE rule_type = 'word' ".
  170. "AND ( blog_id = '".$this->con->escape($this->core->blog->id)."' ".
  171. "OR blog_id IS NULL ) ".
  172. 'ORDER BY blog_id ASC, rule_content ASC ';
  173. return $this->con->select($strReq);
  174. }
  175. private function addRule($content,$general=false)
  176. {
  177. $strReq = 'SELECT rule_id FROM '.$this->table.' '.
  178. "WHERE rule_type = 'word' ".
  179. "AND rule_content = '".$this->con->escape($content)."' ";
  180. if (!$general) {
  181. $strReq .= ' AND blog_id = \''.$this->core->blog->id.'\'';
  182. }
  183. $rs = $this->con->select($strReq);
  184. if (!$rs->isEmpty() && !$general) {
  185. throw new Exception(__('This word exists'));
  186. }
  187. $cur = $this->con->openCursor($this->table);
  188. $cur->rule_type = 'word';
  189. $cur->rule_content = (string) $content;
  190. if ($general && $this->core->auth->isSuperAdmin()) {
  191. $cur->blog_id = null;
  192. } else {
  193. $cur->blog_id = $this->core->blog->id;
  194. }
  195. if (!$rs->isEmpty() && $general) {
  196. $cur->update('WHERE rule_id = '.$rs->rule_id);
  197. } else {
  198. $rs_max = $this->con->select('SELECT MAX(rule_id) FROM '.$this->table);
  199. $cur->rule_id = (integer) $rs_max->f(0) + 1;
  200. $cur->insert();
  201. }
  202. }
  203. private function removeRule($ids)
  204. {
  205. $strReq = 'DELETE FROM '.$this->table.' ';
  206. if (is_array($ids)) {
  207. foreach ($ids as &$v) {
  208. $v = (integer) $v;
  209. }
  210. $strReq .= 'WHERE rule_id IN ('.implode(',',$ids).') ';
  211. } else {
  212. $ids = (integer) $ids;
  213. $strReq .= 'WHERE rule_id = '.$ids.' ';
  214. }
  215. if (!$this->core->auth->isSuperAdmin()) {
  216. $strReq .= "AND blog_id = '".$this->con->escape($this->core->blog->id)."' ";
  217. }
  218. $this->con->execute($strReq);
  219. }
  220. public function defaultWordsList()
  221. {
  222. $words = array(
  223. '/-credit(\s+|$)/',
  224. '/-digest(\s+|$)/',
  225. '/-loan(\s+|$)/',
  226. '/-online(\s+|$)/',
  227. '4u',
  228. 'adipex',
  229. 'advicer',
  230. 'ambien',
  231. 'baccarat',
  232. 'baccarrat',
  233. 'blackjack',
  234. 'bllogspot',
  235. 'bolobomb',
  236. 'booker',
  237. 'byob',
  238. 'car-rental-e-site',
  239. 'car-rentals-e-site',
  240. 'carisoprodol',
  241. 'cash',
  242. 'casino',
  243. 'casinos',
  244. 'chatroom',
  245. 'cialis',
  246. 'craps',
  247. 'credit-card',
  248. 'credit-report-4u',
  249. 'cwas',
  250. 'cyclen',
  251. 'cyclobenzaprine',
  252. 'dating-e-site',
  253. 'day-trading',
  254. 'debt',
  255. 'digest-',
  256. 'discount',
  257. 'discreetordering',
  258. 'duty-free',
  259. 'dutyfree',
  260. 'estate',
  261. 'favourits',
  262. 'fioricet',
  263. 'flowers-leading-site',
  264. 'freenet',
  265. 'freenet-shopping',
  266. 'gambling',
  267. 'gamias',
  268. 'health-insurancedeals-4u',
  269. 'holdem',
  270. 'holdempoker',
  271. 'holdemsoftware',
  272. 'holdemtexasturbowilson',
  273. 'hotel-dealse-site',
  274. 'hotele-site',
  275. 'hotelse-site',
  276. 'incest',
  277. 'insurance-quotesdeals-4u',
  278. 'insurancedeals-4u',
  279. 'jrcreations',
  280. 'levitra',
  281. 'macinstruct',
  282. 'mortgage',
  283. 'online-gambling',
  284. 'onlinegambling-4u',
  285. 'ottawavalleyag',
  286. 'ownsthis',
  287. 'palm-texas-holdem-game',
  288. 'paxil',
  289. 'pharmacy',
  290. 'phentermine',
  291. 'pills',
  292. 'poker',
  293. 'poker-chip',
  294. 'poze',
  295. 'prescription',
  296. 'rarehomes',
  297. 'refund',
  298. 'rental-car-e-site',
  299. 'roulette',
  300. 'shemale',
  301. 'slot',
  302. 'slot-machine',
  303. 'soma',
  304. 'taboo',
  305. 'tamiflu',
  306. 'texas-holdem',
  307. 'thorcarlson',
  308. 'top-e-site',
  309. 'top-site',
  310. 'tramadol',
  311. 'trim-spa',
  312. 'ultram',
  313. 'v1h',
  314. 'vacuum',
  315. 'valeofglamorganconservatives',
  316. 'viagra',
  317. 'vicodin',
  318. 'vioxx',
  319. 'xanax',
  320. 'zolus'
  321. );
  322. foreach ($words as $w) {
  323. try {
  324. $this->addRule($w,true);
  325. } catch (Exception $e) {}
  326. }
  327. }
  328. }