3 * StatusNet - the distributed open-source microblogging tool
4 * Copyright (C) 2011,2012, StatusNet, Inc.
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Affero General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Affero General Public License for more details.
20 * You should have received a copy of the GNU Affero General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 * @author Evan Prodromou <evan@status.net>
26 * @copyright 2011,2012 StatusNet, Inc.
27 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
28 * @link http://status.net/
31 if (!defined('STATUSNET')) {
32 // This check helps protect against security problems;
33 // your code file can't be executed directly from the web.
38 * Check new notices with activity spam service.
42 * @author Evan Prodromou <evan@status.net>
43 * @copyright 2011,2012 StatusNet, Inc.
44 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
45 * @link http://status.net/
47 class ActivitySpamPlugin extends Plugin
49 public $server = null;
50 public $hideSpam = false;
52 const REVIEWSPAM = 'ActivitySpamPlugin::REVIEWSPAM';
53 const TRAINSPAM = 'ActivitySpamPlugin::TRAINSPAM';
58 * @return boolean hook value; true means continue processing, false means stop.
62 $this->filter = new SpamFilter(common_config('activityspam', 'server'),
63 common_config('activityspam', 'consumerkey'),
64 common_config('activityspam', 'secret'));
66 $this->hideSpam = common_config('activityspam', 'hidespam');
68 // Let DB_DataObject find Spam_score
70 common_config_set('db', 'class_location',
71 common_config('db', 'class_location') .':'.dirname(__FILE__));
77 * Database schema setup
82 * @return boolean hook value; true means continue processing, false means stop.
85 function onCheckSchema()
87 $schema = Schema::get();
88 $schema->ensureTable('spam_score', Spam_score::schemaDef());
90 Spam_score::upgrade();
96 * Load related modules when needed
98 * @param string $cls Name of the class to be loaded
100 * @return boolean hook value; true means continue processing, false means stop.
103 function onAutoload($cls)
105 $dir = dirname(__FILE__);
111 include_once $dir . '/' . strtolower(mb_substr($cls, 0, -6)) . '.php';
114 include_once $dir . '/'.$cls.'.php';
117 case 'SpamNoticeStream':
118 case 'TrainSpamForm':
120 include_once $dir . '/'.strtolower($cls).'.php';
128 * When a notice is saved, check its spam score
130 * @param Notice $notice Notice that was just saved
132 * @return boolean hook value; true means continue processing, false means stop.
135 function onEndNoticeSave($notice)
139 $result = $this->filter->test($notice);
141 $score = Spam_score::saveNew($notice, $result);
143 $this->log(LOG_INFO, "Notice " . $notice->id . " has spam score " . $score->score);
145 } catch (Exception $e) {
147 $this->log(LOG_ERR, $e->getMessage());
153 function onNoticeDeleteRelated($notice) {
154 $score = Spam_score::staticGet('notice_id', $notice->id);
155 if (!empty($score)) {
161 function onUserRightsCheck($profile, $right, &$result) {
163 case self::REVIEWSPAM:
164 case self::TRAINSPAM:
165 $result = ($profile->hasRole(Profile_role::MODERATOR) || $profile->hasRole('modhelper'));
172 function onGetSpamFilter(&$filter) {
173 $filter = $this->filter;
177 function onEndShowNoticeOptionItems($nli)
179 $profile = Profile::current();
181 if (!empty($profile) && $profile->hasRight(self::TRAINSPAM)) {
183 $notice = $nli->getNotice();
184 $out = $nli->getOut();
186 if (!empty($notice)) {
188 $score = Spam_score::staticGet('notice_id', $notice->id);
191 // If it's empty, we can train it.
192 $form = new TrainSpamForm($out, $notice);
194 } else if ($score->is_spam) {
195 $form = new TrainHamForm($out, $notice);
197 } else if (!$score->is_spam) {
198 $form = new TrainSpamForm($out, $notice);
208 * Map URLs to actions
210 * @param Net_URL_Mapper $m path-to-action mapper
212 * @return boolean hook value; true means continue processing, false means stop.
215 function onRouterInitialized($m)
217 $m->connect('main/train/spam',
218 array('action' => 'train', 'category' => 'spam'));
219 $m->connect('main/train/ham',
220 array('action' => 'train', 'category' => 'ham'));
221 $m->connect('main/spam',
222 array('action' => 'spam'));
226 function onEndShowStyles($action)
228 $action->element('style', null,
229 '.form-train-spam input.submit { background: url('.$this->path('icons/bullet_black.png').') no-repeat 0px 0px } ' . "\n" .
230 '.form-train-ham input.submit { background: url('.$this->path('icons/exclamation.png').') no-repeat 0px 0px } ');
234 function onEndPublicGroupNav($nav)
236 $user = common_current_user();
238 if (!empty($user) && $user->hasRight(self::REVIEWSPAM)) {
239 $nav->out->menuItem(common_local_url('spam'),
241 // TRANS: Menu item title in search group navigation panel.
242 _('Notices marked as spam'),
243 $nav->actionName == 'spam',
244 'nav_timeline_spam');
250 function onPluginVersion(&$versions)
252 $versions[] = array('name' => 'ActivitySpam',
253 'version' => STATUSNET_VERSION,
254 'author' => 'Evan Prodromou',
255 'homepage' => 'http://status.net/wiki/Plugin:ActivitySpam',
257 _m('Test notices against the Activity Spam service.'));
261 function onEndNoticeInScope($notice, $profile, &$bResult)
263 if ($this->hideSpam) {
266 $score = Spam_score::staticGet('notice_id', $notice->id);
268 if (!empty($score) && $score->is_spam) {
269 if (empty($profile) ||
270 ($profile->id !== $notice->profile_id &&
271 !$profile->hasRight(self::REVIEWSPAM))) {
282 * Pre-cache our spam scores if needed.
284 function onEndNoticeListPrefill(&$notices, &$profiles, $avatarSize) {
285 if ($this->hideSpam) {
286 foreach ($notices as $notice) {
287 $ids[] = $notice->id;
289 Memcached_DataObject::multiGet('Spam_score', 'notice_id', $ids);