带有 SQL-UNION 的 Moodle 过滤器

Moodle Filters with SQL-UNION

当 SQL 查询中出现 UNION 时,我们如何才能使用 moodle 过滤器。下面的代码显示了过滤器不起作用的过滤器表单。该代码在不使用 UNION 时有效。

require_once($CFG->dirroot.'/filter_form.php');    
$mform = new filter_form();
$firstnamefilter = '';
$lastnamefilter = '';
if ($formdata = $mform->get_data()) {
    $firstnamefilter = $formdata->firstname;
    $lastnamefilter = $formdata->lastname;
}

$toform->id = $id;
$mform->set_data($toform);
$mform->display();

$reporttable = new html_table();
$reporttable->head = array('Name', 'Email');
$reporttable->attributes['class'] = 'table';

$sql = "SELECT u.id, u.username, u.firstname, u.lastname, u.email FROM {user} JOIN {user_enrolments} ue
        ON u.id= ue.userid WHERE u.id = '.$id.'

        UNION

        SELECT ae.id, ae.username, ae.firstname, ae.lastname, ae.email FROM {auth_user} JOIN {user_enrolments} ue
        ON ae.id= ue.userid WHERE u.id = '.$id.'

        ";

$params = array();
if (!empty($firstnamefilter)) {
    $params['firstname'] = '%' . $DB->sql_like_escape($firstnamefilter) . '%';  
    $sql .= " AND " . $DB->sql_like('u.firstname', ':firstname', false);

} else if (!empty($lastnamefilter)) {
    $params['lastname'] = '%' . $DB->sql_like_escape($lastnamefilter) . '%';    
    $sql .= " AND " . $DB->sql_like('u.lastname', ':lastname', false);
}

$mds = $DB->get_recordset_sql($sql, $params);

foreach ($mds $m) {

    $reporttable->data[] = new html_table_row(array(implode(array($m->firstname. $m->lastname)), $m->email ));
}                              
echo html_writer::table($reporttable);  

太棒了,你使用了正确的 like 函数!

对于 SQL,您需要为每个联合使用单独的 where 而不是在末尾。您还使用了 u.id = $id,这会将其限制为一个用户 ID。

所以我修改了你的 SQL - 这应该有效。

$params = array();
$wheres1 = array();
$wheres2 = array();

if (!empty($firstnamefilter)) {
    $params['firstname1'] = '%' . $DB->sql_like_escape($firstnamefilter) . '%';
    $params['firstname2'] = $params['firstname1'];
    $wheres1[] = $DB->sql_like('u.firstname', ':firstname1', false);
    $wheres2[] = $DB->sql_like('ae.firstname', ':firstname2', false);
}

if (!empty($lastnamefilter)) {
    $params['lastname1'] = '%' . $DB->sql_like_escape($lastnamefilter) . '%';
    $params['lastname2'] = $params['lastname1'];
    $wheres1[] = $DB->sql_like('u.lastname', ':lastname1', false);
    $wheres2[] = $DB->sql_like('ae.lastname', ':lastname2', false);
}

$where1 = '';
$where2 = '';
if (!empty($wheres1)) {
    $where1 = "WHERE " . implode(" AND ", $wheres1);
    $where2 = "WHERE " . implode(" AND ", $wheres2);
}

$sql = "SELECT u.id, u.username, u.firstname, u.lastname, u.email
        FROM {user} u
        JOIN {user_enrolments} ue ON u.id = ue.userid
        {$where1}

        UNION

        SELECT ae.id, ae.username, ae.firstname, ae.lastname, ae.email
        FROM {auth_user} ae
        JOIN {user_enrolments} ue ON ae.id = ue.userid
        {$where2}";