6 * Helps an admin to clean up spam in Moodle
8 * @author Dongsheng Cai
9 * @author Martin Dougiamas
11 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
14 // List of known spammy keywords, please add more here
16 /////////////////////////////////////////////////////////////////////////////////
18 require_once('../../../config.php');
19 require_once($CFG->libdir
.'/adminlib.php');
24 $autokeywords = array(
36 $keyword = optional_param('keyword', '', PARAM_RAW
);
37 $autodetect = optional_param('autodetect', '', PARAM_RAW
);
38 $del = optional_param('del', '', PARAM_RAW
);
39 $delall = optional_param('delall', '', PARAM_RAW
);
40 $ignore = optional_param('ignore', '', PARAM_RAW
);
41 $reset = optional_param('reset', '', PARAM_RAW
);
42 $id = optional_param('id', '', PARAM_INT
);
45 admin_externalpage_setup('toolspamcleaner');
48 if (!empty($del) && confirm_sesskey() && ($id != $USER->id
)) {
49 if (isset($SESSION->users_result
[$id])) {
50 $user = $SESSION->users_result
[$id];
51 if (delete_user($user)) {
52 unset($SESSION->users_result
[$id]);
53 echo json_encode(true);
55 echo json_encode(false);
58 echo json_encode(false);
63 // Delete lots of users
64 if (!empty($delall) && confirm_sesskey()) {
65 if (!empty($SESSION->users_result
)) {
66 foreach ($SESSION->users_result
as $userid => $user) {
67 if ($userid != $USER->id
) {
68 if (delete_user($user)) {
69 unset($SESSION->users_result
[$userid]);
74 echo json_encode(true);
78 if (!empty($ignore) && confirm_sesskey()) {
79 unset($SESSION->users_result
[$id]);
80 echo json_encode(true);
84 $PAGE->requires
->js_init_call('M.tool_spamcleaner.init', array(me()), true);
85 $strings = Array('spaminvalidresult','spamdeleteallconfirm','spamcannotdelete','spamdeleteconfirm');
86 $PAGE->requires
->strings_for_js($strings, 'tool_spamcleaner');
88 echo $OUTPUT->header();
90 // Print headers and things
91 echo $OUTPUT->box(get_string('spamcleanerintro', 'tool_spamcleaner'));
93 echo $OUTPUT->box_start(); // The forms section at the top
97 <div
class="mdl-align">
99 <form method
="post" action
="index.php" class="form-inline spamcleanerform">
101 <label
class="accesshide" for="keyword_el"><?php
print_string('spamkeyword', 'tool_spamcleaner') ?
></label
>
102 <input type
="text" class="form-control" name
="keyword" id
="keyword_el" value
="<?php p($keyword) ?>" />
103 <input type
="hidden" name
="sesskey" value
="<?php echo sesskey();?>" />
104 <input type
="submit" class="btn btn-primary" value
="<?php echo get_string('spamsearch', 'tool_spamcleaner')?>" />
107 <p
><?php
echo get_string('spameg', 'tool_spamcleaner');?
></p
>
111 <form method
="post" action
="index.php">
113 <input type
="submit" class="btn btn-primary" name
="autodetect"
114 value
="<?php echo get_string('spamauto', 'tool_spamcleaner');?>" />
122 echo $OUTPUT->box_end();
124 echo '<div id="result" class="mdl-align">';
126 // Print list of resulting profiles
128 if (!empty($keyword)) { // Use the keyword(s) supplied by the user
129 $keywords = explode(',', $keyword);
130 foreach ($keywords as $key => $keyword) {
131 $keywords[$key] = trim($keyword);
133 search_spammers($keywords);
135 } else if (!empty($autodetect)) { // Use the inbuilt keyword list to detect users
136 search_spammers($autokeywords);
141 /////////////////////////////////////////////////////////////////////////////////
147 function search_spammers($keywords) {
149 global $CFG, $USER, $DB, $OUTPUT;
151 if (!is_array($keywords)) {
152 $keywords = array($keywords); // Make it into an array
155 $params = array('userid'=>$USER->id
);
157 $keywordfull = array();
159 foreach ($keywords as $keyword) {
160 $keywordfull[] = $DB->sql_like('description', ':descpat'.$i, false);
161 $params['descpat'.$i] = "%$keyword%";
162 $keywordfull2[] = $DB->sql_like('p.summary', ':sumpat'.$i, false);
163 $params['sumpat'.$i] = "%$keyword%";
164 $keywordfull3[] = $DB->sql_like('p.subject', ':subpat'.$i, false);
165 $params['subpat'.$i] = "%$keyword%";
166 $keywordfull4[] = $DB->sql_like('c.content', ':contpat'.$i, false);
167 $params['contpat'.$i] = "%$keyword%";
168 $keywordfull5[] = $DB->sql_like('m.fullmessage', ':msgpat'.$i, false);
169 $params['msgpat'.$i] = "%$keyword%";
170 $keywordfull6[] = $DB->sql_like('fp.message', ':forumpostpat'.$i, false);
171 $params['forumpostpat'.$i] = "%$keyword%";
172 $keywordfull7[] = $DB->sql_like('fp.subject', ':forumpostsubpat'.$i, false);
173 $params['forumpostsubpat'.$i] = "%$keyword%";
176 $conditions = '( '.implode(' OR ', $keywordfull).' )';
177 $conditions2 = '( '.implode(' OR ', $keywordfull2).' )';
178 $conditions3 = '( '.implode(' OR ', $keywordfull3).' )';
179 $conditions4 = '( '.implode(' OR ', $keywordfull4).' )';
180 $conditions5 = '( '.implode(' OR ', $keywordfull5).' )';
181 $conditions6 = '( '.implode(' OR ', $keywordfull6).' )';
182 $conditions7 = '( '.implode(' OR ', $keywordfull7).' )';
188 AND $conditions"; // Exclude oneself
189 $sql2 = "SELECT u.*, p.summary
190 FROM {user} u, {post} p
194 AND u.id <> :userid";
195 $sql3 = "SELECT u.*, p.subject AS postsubject
196 FROM {user} u, {post} p
200 AND u.id <> :userid";
201 $sql4 = "SELECT u.*, c.content
202 FROM {user} u, {comments} c
206 AND u.id <> :userid";
207 $sql5 = "SELECT u.*, m.fullmessage
208 FROM {user} u, {message} m
211 AND u.id=m.useridfrom
212 AND u.id <> :userid";
213 $sql6 = "SELECT u.*, fp.message
214 FROM {user} u, {forum_posts} fp
218 AND u.id <> :userid";
219 $sql7 = "SELECT u.*, fp.subject
220 FROM {user} u, {forum_posts} fp
224 AND u.id <> :userid";
226 $spamusers_desc = $DB->get_recordset_sql($sql, $params);
227 $spamusers_blog = $DB->get_recordset_sql($sql2, $params);
228 $spamusers_blogsub = $DB->get_recordset_sql($sql3, $params);
229 $spamusers_comment = $DB->get_recordset_sql($sql4, $params);
230 $spamusers_message = $DB->get_recordset_sql($sql5, $params);
231 $spamusers_forumpost = $DB->get_recordset_sql($sql6, $params);
232 $spamusers_forumpostsub = $DB->get_recordset_sql($sql7, $params);
234 $keywordlist = implode(', ', $keywords);
235 echo $OUTPUT->box(get_string('spamresult', 'tool_spamcleaner').s($keywordlist)).' ...';
243 $spamusers_forumpost,
244 $spamusers_forumpostsub
246 print_user_list($recordsets, $keywords);
247 foreach ($recordsets as $rs) {
254 function print_user_list($users_rs, $keywords) {
255 global $CFG, $SESSION;
257 // reset session everytime this function is called
258 $SESSION->users_result
= array();
261 foreach ($users_rs as $rs){
262 foreach ($rs as $user) {
264 echo '<table class="table table-bordered" border="1" width="100%" id="data-grid"><tr><th> </th>
265 <th>'.get_string('user', 'admin').'</th><th>'.get_string('spamdesc', 'tool_spamcleaner').'</th>
266 <th>'.get_string('spamoperation', 'tool_spamcleaner').'</th></tr>';
269 filter_user($user, $keywords, $count);
274 echo get_string('spamcannotfinduser', 'tool_spamcleaner');
278 echo '<div class="mld-align">
279 <button id="removeall_btn" class="btn btn-secondary">'.get_string('spamdeleteall', 'tool_spamcleaner').'</button>
283 function filter_user($user, $keywords, $count) {
285 $image_search = false;
286 if (in_array('<img', $keywords)) {
287 $image_search = true;
289 if (isset($user->summary
)) {
290 $user->description
= '<h3>'.get_string('spamfromblog', 'tool_spamcleaner').'</h3>'.$user->summary
;
291 unset($user->summary
);
292 } else if (isset($user->postsubject
)) {
293 $user->description
= '<h3>'.get_string('spamfromblog', 'tool_spamcleaner').'</h3>'.$user->postsubject
;
294 unset($user->postsubject
);
295 } else if (isset($user->content
)) {
296 $user->description
= '<h3>'.get_string('spamfromcomments', 'tool_spamcleaner').'</h3>'.$user->content
;
297 unset($user->content
);
298 } else if (isset($user->fullmessage
)) {
299 $user->description
= '<h3>'.get_string('spamfrommessages', 'tool_spamcleaner').'</h3>'.$user->fullmessage
;
300 unset($user->fullmessage
);
301 } else if (isset($user->message
)) {
302 $user->description
= '<h3>'.get_string('spamfromforumpost', 'tool_spamcleaner').'</h3>'.$user->message
;
303 unset($user->message
);
304 } else if (isset($user->subject
)) {
305 $user->description
= '<h3>'.get_string('spamfromforumpost', 'tool_spamcleaner').'</h3>'.$user->subject
;
306 unset($user->subject
);
309 if (preg_match('#<img.*src=[\"\']('.$CFG->wwwroot
.')#', $user->description
, $matches)
312 foreach ($keywords as $keyword) {
313 if (preg_match('#'.$keyword.'#', $user->description
)
314 && ($keyword != '<img')) {
319 echo print_user_entry($user, $keywords, $count);
324 echo print_user_entry($user, $keywords, $count);
329 function print_user_entry($user, $keywords, $count) {
331 global $SESSION, $CFG;
333 $smalluserobject = new stdClass(); // All we need to delete them later
334 $smalluserobject->id
= $user->id
;
335 $smalluserobject->email
= $user->email
;
336 $smalluserobject->auth
= $user->auth
;
337 $smalluserobject->firstname
= $user->firstname
;
338 $smalluserobject->lastname
= $user->lastname
;
339 $smalluserobject->username
= $user->username
;
341 if (empty($SESSION->users_result
[$user->id
])) {
342 $SESSION->users_result
[$user->id
] = $smalluserobject;
343 $html = '<tr valign="top" id="row-'.$user->id
.'" class="result-row">';
344 $html .= '<td width="10">'.$count.'</td>';
345 $html .= '<td width="30%" align="left"><a href="'.$CFG->wwwroot
."/user/view.php?course=1&id=".$user->id
.'" title="'.s($user->username
).'">'.fullname($user).'</a>';
348 $profile_set = array('city'=>true, 'country'=>true, 'email'=>true);
349 foreach ($profile_set as $key=>$value) {
350 if (isset($user->$key)){
351 $html .= '<li>'.$user->$key.'</li>';
357 foreach ($keywords as $keyword) {
358 $user->description
= highlight($keyword, $user->description
);
361 if (!isset($user->descriptionformat
)) {
362 $user->descriptionformat
= FORMAT_MOODLE
;
365 $html .= '<td align="left">'.format_text($user->description
, $user->descriptionformat
, array('overflowdiv'=>true)).'</td>';
366 $html .= '<td width="100px" align="center">';
367 $html .= '<button class="btn btn-primary" onclick="M.tool_spamcleaner.del_user(this,'.$user->id
.')">'.
368 get_string('deleteuser', 'admin').'</button><br />';
369 $html .= '<button class="btn btn-secondary" onclick="M.tool_spamcleaner.ignore_user(this,'.$user->id
.')">'.
370 get_string('ignore', 'admin').'</button>';
381 echo $OUTPUT->footer();