<commit_before><?php

/**
 * Spam Cleaner
 *
 * Helps an admin to clean up spam in Moodle
 *
 * @authors <NAME>, <NAME>, <NAME>
 * @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);

require_login();
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)) {
    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">
  <div>
    <label class="accesshide" for="keyword_el"><?php print_string('spamkeyword', 'tool_spamcleaner') ?></label>
    <input type="text" name="keyword" id="keyword_el" value="<?php p($keyword) ?>" />
    <input type="hidden" name="sesskey" value="<?php echo sesskey();?>" />
    <input type="submit" 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" 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} AS u, {post} AS 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} AS u, {post} AS p WHERE $conditions3 AND u.deleted = 0 AND u.id=p.userid AND u.id <> :userid";
    $sql4 = "SELECT u.*, c.content FROM {user} AS u, {comments} AS c WHERE $conditions4 AND u.deleted = 0 AND u.id=c.userid AND u.id <> :userid";
    $sql5 = "SELECT u.*, m.fullmessage FROM {user} AS u, {message} AS m WHERE $conditions5 AND u.deleted = 0 AND u.id=m.useridfrom AND u.id <> :userid";
    $sql6 = "SELECT u.*, fp.message FROM {user} AS u, {forum_posts} AS fp WHERE $conditions6 AND u.deleted = 0 AND u.id=fp.userid AND u.id <> :userid";
    $sql7 = "SELECT u.*, fp.subject FROM {user} AS u, {forum_posts} AS 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)).' ...';

    print_user_list(array($spamusers_desc,
                          $spamusers_blog,
                          $spamusers_blogsub,
                          $spamusers_comment,
                          $spamusers_message,
                          $spamusers_forumpost,
                          $spamusers_forumpostsub
                         ),
                         $keywords);
}



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 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">'.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 onclick="M.tool_spamcleaner.del_user(this,'.$user->id.')">'.get_string('deleteuser', 'admin').'</button><br />';
        $html .= '<button 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();
<commit_msg>MDL-41316 tool_spamcleaner: Fix sql queries<commit_after><?php

/**
 * Spam Cleaner
 *
 * Helps an admin to clean up spam in Moodle
 *
 * @authors <NAME>, <NAME>, <NAME>
 * @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);

require_login();
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)) {
    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">
  <div>
    <label class="accesshide" for="keyword_el"><?php print_string('spamkeyword', 'tool_spamcleaner') ?></label>
    <input type="text" name="keyword" id="keyword_el" value="<?php p($keyword) ?>" />
    <input type="hidden" name="sesskey" value="<?php echo sesskey();?>" />
    <input type="submit" 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" 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)).' ...';

    print_user_list(array($spamusers_desc,
                          $spamusers_blog,
                          $spamusers_blogsub,
                          $spamusers_comment,
                          $spamusers_message,
                          $spamusers_forumpost,
                          $spamusers_forumpostsub
                         ),
                         $keywords);
}



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 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">'.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 onclick="M.tool_spamcleaner.del_user(this,'.$user->id.')">'.get_string('deleteuser', 'admin').'</button><br />';
        $html .= '<button 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();

{'fraction_non_alphanumeric': 0.20579110651499483, 'fraction_numerical': 0.005687693898655636, 'mean_word_length': 2.482409972299169, 'pattern_counts': {'":': 0, '<': 187, '<?xml version=': 0, '>': 379, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '949432', 'n_tokens_mistral': 8216, 'n_tokens_neox': 8028, 'n_words': 1508}