MDL-60915 core_dml: fix miscellaneous incorrect recordset usage
[moodle.git] / admin / tool / spamcleaner / index.php
blob2f98bf4100678140996317a1bed9247fe7ffebaf
1 <?php
3 /**
4 * Spam Cleaner
6 * Helps an admin to clean up spam in Moodle
8 * @author Dongsheng Cai
9 * @author Martin Dougiamas
10 * @author Amr Hourani
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');
22 // Configuration
24 $autokeywords = array(
25 "<img",
26 "fuck",
27 "casino",
28 "porn",
29 "xxx",
30 "cialis",
31 "viagra",
32 "poker",
33 "warcraft"
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);
44 require_login();
45 admin_externalpage_setup('toolspamcleaner');
47 // Delete one user
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);
54 } else {
55 echo json_encode(false);
57 } else {
58 echo json_encode(false);
60 exit;
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);
75 exit;
78 if (!empty($ignore) && confirm_sesskey()) {
79 unset($SESSION->users_result[$id]);
80 echo json_encode(true);
81 exit;
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">
100 <div>
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')?>" />
105 </div>
106 </form>
107 <p><?php echo get_string('spameg', 'tool_spamcleaner');?></p>
109 <hr />
111 <form method="post" action="index.php">
112 <div>
113 <input type="submit" class="btn btn-primary" name="autodetect"
114 value="<?php echo get_string('spamauto', 'tool_spamcleaner');?>" />
115 </div>
116 </form>
119 </div>
121 <?php
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);
139 echo '</div>';
141 /////////////////////////////////////////////////////////////////////////////////
144 /// Functions
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();
158 $i = 0;
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%";
174 $i++;
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).' )';
184 $sql = "SELECT *
185 FROM {user}
186 WHERE deleted = 0
187 AND id <> :userid
188 AND $conditions"; // Exclude oneself
189 $sql2 = "SELECT u.*, p.summary
190 FROM {user} u, {post} p
191 WHERE $conditions2
192 AND u.deleted = 0
193 AND u.id=p.userid
194 AND u.id <> :userid";
195 $sql3 = "SELECT u.*, p.subject AS postsubject
196 FROM {user} u, {post} p
197 WHERE $conditions3
198 AND u.deleted = 0
199 AND u.id=p.userid
200 AND u.id <> :userid";
201 $sql4 = "SELECT u.*, c.content
202 FROM {user} u, {comments} c
203 WHERE $conditions4
204 AND u.deleted = 0
205 AND u.id=c.userid
206 AND u.id <> :userid";
207 $sql5 = "SELECT u.*, m.fullmessage
208 FROM {user} u, {message} m
209 WHERE $conditions5
210 AND u.deleted = 0
211 AND u.id=m.useridfrom
212 AND u.id <> :userid";
213 $sql6 = "SELECT u.*, fp.message
214 FROM {user} u, {forum_posts} fp
215 WHERE $conditions6
216 AND u.deleted = 0
217 AND u.id=fp.userid
218 AND u.id <> :userid";
219 $sql7 = "SELECT u.*, fp.subject
220 FROM {user} u, {forum_posts} fp
221 WHERE $conditions7
222 AND u.deleted = 0
223 AND u.id=fp.userid
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)).' ...';
237 $recordsets = [
238 $spamusers_desc,
239 $spamusers_blog,
240 $spamusers_blogsub,
241 $spamusers_comment,
242 $spamusers_message,
243 $spamusers_forumpost,
244 $spamusers_forumpostsub
246 print_user_list($recordsets, $keywords);
247 foreach ($recordsets as $rs) {
248 $rs->close();
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();
259 $count = 0;
261 foreach ($users_rs as $rs){
262 foreach ($rs as $user) {
263 if (!$count) {
264 echo '<table class="table table-bordered" border="1" width="100%" id="data-grid"><tr><th>&nbsp;</th>
265 <th>'.get_string('user', 'admin').'</th><th>'.get_string('spamdesc', 'tool_spamcleaner').'</th>
266 <th>'.get_string('spamoperation', 'tool_spamcleaner').'</th></tr>';
268 $count++;
269 filter_user($user, $keywords, $count);
273 if (!$count) {
274 echo get_string('spamcannotfinduser', 'tool_spamcleaner');
276 } else {
277 echo '</table>';
278 echo '<div class="mld-align">
279 <button id="removeall_btn" class="btn btn-secondary">'.get_string('spamdeleteall', 'tool_spamcleaner').'</button>
280 </div>';
283 function filter_user($user, $keywords, $count) {
284 global $CFG;
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)
310 && $image_search) {
311 $result = false;
312 foreach ($keywords as $keyword) {
313 if (preg_match('#'.$keyword.'#', $user->description)
314 && ($keyword != '<img')) {
315 $result = true;
318 if ($result) {
319 echo print_user_entry($user, $keywords, $count);
320 } else {
321 unset($user);
323 } else {
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&amp;id=".$user->id.'" title="'.s($user->username).'">'.fullname($user).'</a>';
347 $html .= "<ul>";
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>';
354 $html .= "</ul>";
355 $html .= '</td>';
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>';
371 $html .= '</td>';
372 $html .= '</tr>';
373 return $html;
374 } else {
375 return null;
381 echo $OUTPUT->footer();