Фильтры Moodle с SQL -UNION - PullRequest
       79

Фильтры Moodle с SQL -UNION

0 голосов
/ 01 мая 2020

Как мы можем заставить работать фильтры Moodle, когда UNION появляется в запросе SQL. Приведенный ниже код показывает форму фильтра, где фильтры не работают. Код работает, когда 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);  

1 Ответ

0 голосов
/ 01 мая 2020

Здорово, что вы используете правильные подобные функции!

Для SQL вам нужно использовать отдельное где для каждого объединения, а не в конце. Вы также использовали u.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}";
...