first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,46 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Privacy Subsystem implementation for tool_spamcleaner.
*
* @package tool_spamcleaner
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_spamcleaner\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for tool_spamcleaner implementing null_provider.
*
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+380
View File
@@ -0,0 +1,380 @@
<?php
/**
* Spam Cleaner
*
* Helps an admin to clean up spam in Moodle
*
* @author Dongsheng Cai
* @author Martin Dougiamas
* @author Amr Hourani
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
*/
// List of known spammy keywords, please add more here
/////////////////////////////////////////////////////////////////////////////////
require_once('../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
// Configuration
$autokeywords = array(
"<img",
"fuck",
"casino",
"porn",
"xxx",
"cialis",
"viagra",
"poker",
"warcraft"
);
$keyword = optional_param('keyword', '', PARAM_RAW);
$autodetect = optional_param('autodetect', '', PARAM_RAW);
$del = optional_param('del', '', PARAM_RAW);
$delall = optional_param('delall', '', PARAM_RAW);
$ignore = optional_param('ignore', '', PARAM_RAW);
$reset = optional_param('reset', '', PARAM_RAW);
$id = optional_param('id', '', PARAM_INT);
admin_externalpage_setup('toolspamcleaner');
// Delete one user
if (!empty($del) && confirm_sesskey() && ($id != $USER->id)) {
if (isset($SESSION->users_result[$id])) {
$user = $SESSION->users_result[$id];
if (delete_user($user)) {
unset($SESSION->users_result[$id]);
echo json_encode(true);
} else {
echo json_encode(false);
}
} else {
echo json_encode(false);
}
exit;
}
// Delete lots of users
if (!empty($delall) && confirm_sesskey()) {
if (!empty($SESSION->users_result)) {
foreach ($SESSION->users_result as $userid => $user) {
if ($userid != $USER->id) {
if (delete_user($user)) {
unset($SESSION->users_result[$userid]);
}
}
}
}
echo json_encode(true);
exit;
}
if (!empty($ignore) && confirm_sesskey()) {
unset($SESSION->users_result[$id]);
echo json_encode(true);
exit;
}
$PAGE->requires->js_init_call('M.tool_spamcleaner.init', array(me()), true);
$strings = Array('spaminvalidresult','spamdeleteallconfirm','spamcannotdelete','spamdeleteconfirm');
$PAGE->requires->strings_for_js($strings, 'tool_spamcleaner');
echo $OUTPUT->header();
// Print headers and things
echo $OUTPUT->box(get_string('spamcleanerintro', 'tool_spamcleaner'));
echo $OUTPUT->box_start(); // The forms section at the top
?>
<div class="mdl-align">
<form method="post" action="index.php" class="d-flex flex-wrap align-items-center spamcleanerform">
<div>
<label class="accesshide" for="keyword_el"><?php print_string('spamkeyword', 'tool_spamcleaner') ?></label>
<input type="text" class="form-control" name="keyword" id="keyword_el" value="<?php p($keyword) ?>" />
<input type="hidden" name="sesskey" value="<?php echo sesskey();?>" />
<input type="submit" class="btn btn-primary" value="<?php echo get_string('spamsearch', 'tool_spamcleaner')?>" />
</div>
</form>
<p><?php echo get_string('spameg', 'tool_spamcleaner');?></p>
<hr />
<form method="post" action="index.php">
<div>
<input type="submit" class="btn btn-primary" name="autodetect"
value="<?php echo get_string('spamauto', 'tool_spamcleaner');?>" />
</div>
</form>
</div>
<?php
echo $OUTPUT->box_end();
echo '<div id="result" class="mdl-align">';
// Print list of resulting profiles
if (!empty($keyword)) { // Use the keyword(s) supplied by the user
$keywords = explode(',', $keyword);
foreach ($keywords as $key => $keyword) {
$keywords[$key] = trim($keyword);
}
search_spammers($keywords);
} else if (!empty($autodetect)) { // Use the inbuilt keyword list to detect users
search_spammers($autokeywords);
}
echo '</div>';
/////////////////////////////////////////////////////////////////////////////////
/// Functions
function search_spammers($keywords) {
global $CFG, $USER, $DB, $OUTPUT;
if (!is_array($keywords)) {
$keywords = array($keywords); // Make it into an array
}
$params = array('userid'=>$USER->id);
$keywordfull = array();
$i = 0;
foreach ($keywords as $keyword) {
$keywordfull[] = $DB->sql_like('description', ':descpat'.$i, false);
$params['descpat'.$i] = "%$keyword%";
$keywordfull2[] = $DB->sql_like('p.summary', ':sumpat'.$i, false);
$params['sumpat'.$i] = "%$keyword%";
$keywordfull3[] = $DB->sql_like('p.subject', ':subpat'.$i, false);
$params['subpat'.$i] = "%$keyword%";
$keywordfull4[] = $DB->sql_like('c.content', ':contpat'.$i, false);
$params['contpat'.$i] = "%$keyword%";
$keywordfull5[] = $DB->sql_like('m.fullmessage', ':msgpat'.$i, false);
$params['msgpat'.$i] = "%$keyword%";
$keywordfull6[] = $DB->sql_like('fp.message', ':forumpostpat'.$i, false);
$params['forumpostpat'.$i] = "%$keyword%";
$keywordfull7[] = $DB->sql_like('fp.subject', ':forumpostsubpat'.$i, false);
$params['forumpostsubpat'.$i] = "%$keyword%";
$i++;
}
$conditions = '( '.implode(' OR ', $keywordfull).' )';
$conditions2 = '( '.implode(' OR ', $keywordfull2).' )';
$conditions3 = '( '.implode(' OR ', $keywordfull3).' )';
$conditions4 = '( '.implode(' OR ', $keywordfull4).' )';
$conditions5 = '( '.implode(' OR ', $keywordfull5).' )';
$conditions6 = '( '.implode(' OR ', $keywordfull6).' )';
$conditions7 = '( '.implode(' OR ', $keywordfull7).' )';
$sql = "SELECT *
FROM {user}
WHERE deleted = 0
AND id <> :userid
AND $conditions"; // Exclude oneself
$sql2 = "SELECT u.*, p.summary
FROM {user} u, {post} p
WHERE $conditions2
AND u.deleted = 0
AND u.id=p.userid
AND u.id <> :userid";
$sql3 = "SELECT u.*, p.subject AS postsubject
FROM {user} u, {post} p
WHERE $conditions3
AND u.deleted = 0
AND u.id=p.userid
AND u.id <> :userid";
$sql4 = "SELECT u.*, c.content
FROM {user} u, {comments} c
WHERE $conditions4
AND u.deleted = 0
AND u.id=c.userid
AND u.id <> :userid";
$sql5 = "SELECT u.*, m.fullmessage
FROM {user} u, {message} m
WHERE $conditions5
AND u.deleted = 0
AND u.id=m.useridfrom
AND u.id <> :userid";
$sql6 = "SELECT u.*, fp.message
FROM {user} u, {forum_posts} fp
WHERE $conditions6
AND u.deleted = 0
AND u.id=fp.userid
AND u.id <> :userid";
$sql7 = "SELECT u.*, fp.subject
FROM {user} u, {forum_posts} fp
WHERE $conditions7
AND u.deleted = 0
AND u.id=fp.userid
AND u.id <> :userid";
$spamusers_desc = $DB->get_recordset_sql($sql, $params);
$spamusers_blog = $DB->get_recordset_sql($sql2, $params);
$spamusers_blogsub = $DB->get_recordset_sql($sql3, $params);
$spamusers_comment = $DB->get_recordset_sql($sql4, $params);
$spamusers_message = $DB->get_recordset_sql($sql5, $params);
$spamusers_forumpost = $DB->get_recordset_sql($sql6, $params);
$spamusers_forumpostsub = $DB->get_recordset_sql($sql7, $params);
$keywordlist = implode(', ', $keywords);
echo $OUTPUT->box(get_string('spamresult', 'tool_spamcleaner').s($keywordlist)).' ...';
$recordsets = [
$spamusers_desc,
$spamusers_blog,
$spamusers_blogsub,
$spamusers_comment,
$spamusers_message,
$spamusers_forumpost,
$spamusers_forumpostsub
];
print_user_list($recordsets, $keywords);
foreach ($recordsets as $rs) {
$rs->close();
}
}
function print_user_list($users_rs, $keywords) {
global $CFG, $SESSION;
// reset session everytime this function is called
$SESSION->users_result = array();
$count = 0;
foreach ($users_rs as $rs){
foreach ($rs as $user) {
if (!$count) {
echo '<table class="table table-bordered" border="1" width="100%" id="data-grid"><tr><th>&nbsp;</th>
<th>'.get_string('user', 'admin').'</th><th>'.get_string('spamdesc', 'tool_spamcleaner').'</th>
<th>'.get_string('spamoperation', 'tool_spamcleaner').'</th></tr>';
}
$count++;
filter_user($user, $keywords, $count);
}
}
if (!$count) {
echo get_string('spamcannotfinduser', 'tool_spamcleaner');
} else {
echo '</table>';
echo '<div class="mld-align">
<button id="removeall_btn" class="btn btn-secondary">'.get_string('spamdeleteall', 'tool_spamcleaner').'</button>
</div>';
}
}
function filter_user($user, $keywords, $count) {
global $CFG;
$image_search = false;
if (in_array('<img', $keywords)) {
$image_search = true;
}
if (isset($user->summary)) {
$user->description = '<h3>'.get_string('spamfromblog', 'tool_spamcleaner').'</h3>'.$user->summary;
unset($user->summary);
} else if (isset($user->postsubject)) {
$user->description = '<h3>'.get_string('spamfromblog', 'tool_spamcleaner').'</h3>'.$user->postsubject;
unset($user->postsubject);
} else if (isset($user->content)) {
$user->description = '<h3>'.get_string('spamfromcomments', 'tool_spamcleaner').'</h3>'.$user->content;
unset($user->content);
} else if (isset($user->fullmessage)) {
$user->description = '<h3>'.get_string('spamfrommessages', 'tool_spamcleaner').'</h3>'.$user->fullmessage;
unset($user->fullmessage);
} else if (isset($user->message)) {
$user->description = '<h3>'.get_string('spamfromforumpost', 'tool_spamcleaner').'</h3>'.$user->message;
unset($user->message);
} else if (isset($user->subject)) {
$user->description = '<h3>'.get_string('spamfromforumpost', 'tool_spamcleaner').'</h3>'.$user->subject;
unset($user->subject);
}
if (preg_match('#<img.*src=[\"\']('.$CFG->wwwroot.')#', $user->description, $matches)
&& $image_search) {
$result = false;
foreach ($keywords as $keyword) {
if (preg_match('#'.$keyword.'#', $user->description)
&& ($keyword != '<img')) {
$result = true;
}
}
if ($result) {
echo print_user_entry($user, $keywords, $count);
} else {
unset($user);
}
} else {
echo print_user_entry($user, $keywords, $count);
}
}
function print_user_entry($user, $keywords, $count) {
global $SESSION, $CFG;
$smalluserobject = new stdClass(); // All we need to delete them later
$smalluserobject->id = $user->id;
$smalluserobject->email = $user->email;
$smalluserobject->auth = $user->auth;
$smalluserobject->firstname = $user->firstname;
$smalluserobject->lastname = $user->lastname;
$smalluserobject->username = $user->username;
if (empty($SESSION->users_result[$user->id])) {
$SESSION->users_result[$user->id] = $smalluserobject;
$html = '<tr valign="top" id="row-'.$user->id.'" class="result-row">';
$html .= '<td width="10">'.$count.'</td>';
$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>';
$html .= "<ul>";
$profile_set = array('city'=>true, 'country'=>true, 'email'=>true);
foreach ($profile_set as $key=>$value) {
if (isset($user->$key)){
$html .= '<li>'.$user->$key.'</li>';
}
}
$html .= "</ul>";
$html .= '</td>';
foreach ($keywords as $keyword) {
$user->description = highlight($keyword, $user->description);
}
if (!isset($user->descriptionformat)) {
$user->descriptionformat = FORMAT_MOODLE;
}
$html .= '<td align="left">'.format_text($user->description, $user->descriptionformat, array('overflowdiv'=>true)).'</td>';
$html .= '<td width="100px" align="center">';
$html .= '<button class="btn btn-primary" onclick="M.tool_spamcleaner.del_user(this,'.$user->id.')">'.
get_string('deleteuser', 'admin').'</button><br />';
$html .= '<button class="btn btn-secondary" onclick="M.tool_spamcleaner.ignore_user(this,'.$user->id.')">'.
get_string('ignore', 'admin').'</button>';
$html .= '</td>';
$html .= '</tr>';
return $html;
} else {
return null;
}
}
echo $OUTPUT->footer();
@@ -0,0 +1,46 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Strings for component 'tool_spamcleaner', language 'en', branch 'MOODLE_22_STABLE'
*
* @package tool
* @subpackage spamcleaner
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'Spam cleaner';
$string['spamauto'] = 'Autodetect common spam patterns';
$string['spamcannotdelete'] = 'Cannot delete this user';
$string['spamcannotfinduser'] = 'No users matching your search';
$string['spamcleanerintro'] = '<p>This script allows you to search all user profiles for certain strings and then delete those accounts which are obviously created by spammers. You can search for multiple keywords using commas (e.g. casino, porn).</p>
<p>For further information, see the documentation <a href="https://docs.moodle.org/en/Reducing_spam_in_Moodle">Reducing spam in Moodle</a>.</p>';
$string['spamdeleteall'] = 'Delete all these user accounts';
$string['spamdeleteallconfirm'] = 'Are you sure you want to delete all these user accounts? You can not undo this.';
$string['spamdeleteconfirm'] = 'Are you sure you want to delete this entry? You can not undo this.';
$string['spamdesc'] = 'Description';
$string['spameg'] = 'eg: casino, porn, xxx';
$string['spamfromblog'] = 'From blog post:';
$string['spamfromcomments'] = 'From comments:';
$string['spamfrommessages'] = 'From messages:';
$string['spamfromforumpost'] = 'From forum post:';
$string['spaminvalidresult'] = 'Unknown but invalid result';
$string['spamkeyword'] = 'Keyword';
$string['spamoperation'] = 'Operation';
$string['spamresult'] = 'Results of searching user profiles containing:';
$string['spamsearch'] = 'Search for these keywords';
$string['privacy:metadata'] = 'The Spam cleaner plugin does not store any personal data.';
+115
View File
@@ -0,0 +1,115 @@
M.tool_spamcleaner = {
Y: null,
row: null,
me: null,
del_all: function() {
var context = M.tool_spamcleaner;
var yes = confirm(M.util.get_string('spamdeleteallconfirm', 'tool_spamcleaner'));
if (yes) {
var cfg = {
method: "POST",
on: {
success : function(id, o, args) {
try {
var resp = context.Y.JSON.parse(o.responseText);
} catch(e) {
alert(M.util.get_string('spaminvalidresult', 'tool_spamcleaner'));
return;
}
if (resp == true) {
window.location.href=window.location.href;
}
}
}
};
context.Y.io(context.me+'?delall=yes&sesskey='+M.cfg.sesskey, cfg);
}
},
del_user: function(obj, id) {
var context = M.tool_spamcleaner;
if (context.Y == null) {
// not initialised yet
return;
}
var yes = confirm(M.util.get_string('spamdeleteconfirm', 'tool_spamcleaner'));
if (yes) {
context.row = obj;
var cfg = {
method: "POST",
on: {
success : function(id, o, args) {
try {
var resp = context.Y.JSON.parse(o.responseText);
} catch(e) {
alert(M.util.get_string('spaminvalidresult', 'tool_spamcleaner'));
return;
}
if (context.row) {
if (resp == true) {
while(context.row.tagName != 'TR') {
context.row = context.row.parentNode;
}
context.row.parentNode.removeChild(context.row);
context.row = null;
} else {
alert(M.util.get_string('spamcannotdelete', 'tool_spamcleaner'));
}
}
}
}
}
context.Y.io(context.me+'?del=yes&sesskey='+M.cfg.sesskey+'&id='+id, cfg);
}
},
ignore_user: function(obj, id) {
var context = M.tool_spamcleaner;
if (context.Y == null) {
// not initilised yet
return;
}
context.row = obj;
var cfg = {
method: "POST",
on: {
success : function(id, o, args) {
try {
var resp = context.Y.JSON.parse(o.responseText);
} catch(e) {
alert(M.util.get_string('spaminvalidresult', 'tool_spamcleaner'));
return;
}
if (context.row) {
if (resp == true){
while(context.row.tagName != 'TR') {
context.row = context.row.parentNode;
}
context.row.parentNode.removeChild(context.row);
context.row = null;
}
}
}
}
}
context.Y.io(context.me+'?ignore=yes&sesskey='+M.cfg.sesskey+'&id='+id, cfg);
},
init: function(Y, me) {
var context = M.tool_spamcleaner;
Y.use('json', 'io-base', function (Y) {
context.Y = Y;
context.me = me;
if (Y.one("#removeall_btn")) {
Y.on("click", context.del_all, "#removeall_btn");
}
});
}
}
+33
View File
@@ -0,0 +1,33 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Link to spamcleaner.
*
* For now keep in Reports folder, we should move it elsewhere once we deal with contexts in general reports and navigation
*
* @package tool
* @subpackage unsuproles
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
if ($hassiteconfig) {
$ADMIN->add('reports', new admin_externalpage('toolspamcleaner', get_string('pluginname', 'tool_spamcleaner'), "$CFG->wwwroot/$CFG->admin/tool/spamcleaner/index.php", 'moodle/site:config'));
}
+31
View File
@@ -0,0 +1,31 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Plugin version info
*
* @package tool
* @subpackage spamcleaner
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200;
$plugin->requires = 2024041600;
$plugin->component = 'tool_spamcleaner'; // Full name of the plugin (used for diagnostics)