| 1 | <?php |
|---|
| 2 | /** |
|---|
| 3 | * @brief antispam, a plugin for Dotclear 2 |
|---|
| 4 | * |
|---|
| 5 | * @package Dotclear |
|---|
| 6 | * @subpackage Plugins |
|---|
| 7 | * |
|---|
| 8 | * @copyright Olivier Meunier & Association Dotclear |
|---|
| 9 | * @copyright GPL-2.0-only |
|---|
| 10 | */ |
|---|
| 11 | |
|---|
| 12 | if (!defined('DC_RC_PATH')) {return;} |
|---|
| 13 | |
|---|
| 14 | class dcSpamFilters |
|---|
| 15 | { |
|---|
| 16 | private $filters = array(); |
|---|
| 17 | private $filters_opt = array(); |
|---|
| 18 | private $core; |
|---|
| 19 | |
|---|
| 20 | public function __construct($core) |
|---|
| 21 | { |
|---|
| 22 | $this->core = &$core; |
|---|
| 23 | } |
|---|
| 24 | |
|---|
| 25 | public function init($filters) |
|---|
| 26 | { |
|---|
| 27 | foreach ($filters as $f) { |
|---|
| 28 | if (!class_exists($f)) { |
|---|
| 29 | continue; |
|---|
| 30 | } |
|---|
| 31 | |
|---|
| 32 | $r = new ReflectionClass($f); |
|---|
| 33 | $p = $r->getParentClass(); |
|---|
| 34 | |
|---|
| 35 | if (!$p || $p->name != 'dcSpamFilter') { |
|---|
| 36 | continue; |
|---|
| 37 | } |
|---|
| 38 | |
|---|
| 39 | $this->filters[$f] = new $f($this->core); |
|---|
| 40 | } |
|---|
| 41 | |
|---|
| 42 | $this->setFilterOpts(); |
|---|
| 43 | if (!empty($this->filters_opt)) { |
|---|
| 44 | uasort($this->filters, array($this, 'orderCallBack')); |
|---|
| 45 | } |
|---|
| 46 | } |
|---|
| 47 | |
|---|
| 48 | public function getFilters() |
|---|
| 49 | { |
|---|
| 50 | return $this->filters; |
|---|
| 51 | } |
|---|
| 52 | |
|---|
| 53 | public function isSpam($cur) |
|---|
| 54 | { |
|---|
| 55 | foreach ($this->filters as $fid => $f) { |
|---|
| 56 | if (!$f->active) { |
|---|
| 57 | continue; |
|---|
| 58 | } |
|---|
| 59 | |
|---|
| 60 | $type = $cur->comment_trackback ? 'trackback' : 'comment'; |
|---|
| 61 | $author = $cur->comment_author; |
|---|
| 62 | $email = $cur->comment_email; |
|---|
| 63 | $site = $cur->comment_site; |
|---|
| 64 | $ip = $cur->comment_ip; |
|---|
| 65 | $content = $cur->comment_content; |
|---|
| 66 | $post_id = $cur->post_id; |
|---|
| 67 | |
|---|
| 68 | $is_spam = $f->isSpam($type, $author, $email, $site, $ip, $content, $post_id, $status); |
|---|
| 69 | |
|---|
| 70 | if ($is_spam === true) { |
|---|
| 71 | if ($f->auto_delete) { |
|---|
| 72 | $cur->clean(); |
|---|
| 73 | } else { |
|---|
| 74 | $cur->comment_status = -2; |
|---|
| 75 | $cur->comment_spam_status = $status; |
|---|
| 76 | $cur->comment_spam_filter = $fid; |
|---|
| 77 | } |
|---|
| 78 | return true; |
|---|
| 79 | } elseif ($is_spam === false) { |
|---|
| 80 | return false; |
|---|
| 81 | } |
|---|
| 82 | } |
|---|
| 83 | |
|---|
| 84 | return false; |
|---|
| 85 | } |
|---|
| 86 | |
|---|
| 87 | public function trainFilters($rs, $status, $filter_name) |
|---|
| 88 | { |
|---|
| 89 | foreach ($this->filters as $fid => $f) { |
|---|
| 90 | if (!$f->active) { |
|---|
| 91 | continue; |
|---|
| 92 | } |
|---|
| 93 | |
|---|
| 94 | $type = $rs->comment_trackback ? 'trackback' : 'comment'; |
|---|
| 95 | $author = $rs->comment_author; |
|---|
| 96 | $email = $rs->comment_email; |
|---|
| 97 | $site = $rs->comment_site; |
|---|
| 98 | $ip = $rs->comment_ip; |
|---|
| 99 | $content = $rs->comment_content; |
|---|
| 100 | |
|---|
| 101 | $f->trainFilter($status, $filter_name, $type, $author, $email, $site, $ip, $content, $rs); |
|---|
| 102 | } |
|---|
| 103 | } |
|---|
| 104 | |
|---|
| 105 | public function statusMessage($rs, $filter_name) |
|---|
| 106 | { |
|---|
| 107 | $f = isset($this->filters[$filter_name]) ? $this->filters[$filter_name] : null; |
|---|
| 108 | |
|---|
| 109 | if ($f === null) { |
|---|
| 110 | return __('Unknown filter.'); |
|---|
| 111 | } else { |
|---|
| 112 | $status = $rs->exists('comment_spam_status') ? $rs->comment_spam_status : null; |
|---|
| 113 | |
|---|
| 114 | return $f->getStatusMessage($status, $rs->comment_id); |
|---|
| 115 | } |
|---|
| 116 | } |
|---|
| 117 | |
|---|
| 118 | public function saveFilterOpts($opts, $global = false) |
|---|
| 119 | { |
|---|
| 120 | $this->core->blog->settings->addNamespace('antispam'); |
|---|
| 121 | if ($global) { |
|---|
| 122 | $this->core->blog->settings->antispam->drop('antispam_filters'); |
|---|
| 123 | } |
|---|
| 124 | $this->core->blog->settings->antispam->put('antispam_filters', $opts, 'array', 'Antispam Filters', true, $global); |
|---|
| 125 | } |
|---|
| 126 | |
|---|
| 127 | private function setFilterOpts() |
|---|
| 128 | { |
|---|
| 129 | if ($this->core->blog->settings->antispam->antispam_filters !== null) { |
|---|
| 130 | $this->filters_opt = $this->core->blog->settings->antispam->antispam_filters; |
|---|
| 131 | } |
|---|
| 132 | |
|---|
| 133 | # Create default options if needed |
|---|
| 134 | if (!is_array($this->filters_opt)) { |
|---|
| 135 | $this->saveFilterOpts(array(), true); |
|---|
| 136 | $this->filters_opt = array(); |
|---|
| 137 | } |
|---|
| 138 | |
|---|
| 139 | foreach ($this->filters_opt as $k => $o) { |
|---|
| 140 | if (isset($this->filters[$k]) && is_array($o)) { |
|---|
| 141 | $this->filters[$k]->active = isset($o[0]) ? $o[0] : false; |
|---|
| 142 | $this->filters[$k]->order = isset($o[1]) ? $o[1] : 0; |
|---|
| 143 | $this->filters[$k]->auto_delete = isset($o[2]) ? $o[2] : false; |
|---|
| 144 | } |
|---|
| 145 | } |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | private function orderCallBack($a, $b) |
|---|
| 149 | { |
|---|
| 150 | if ($a->order == $b->order) { |
|---|
| 151 | return 0; |
|---|
| 152 | } |
|---|
| 153 | |
|---|
| 154 | return $a->order > $b->order ? 1 : -1; |
|---|
| 155 | } |
|---|
| 156 | } |
|---|