From cd1edf9e8aed57231a260bd803c9628595156558 Mon Sep 17 00:00:00 2001 From: skodak Date: Tue, 13 Nov 2007 08:43:20 +0000 Subject: [PATCH] MDL-12101 cleanup/fixing/refactoring of user bulk operation and admin user browsing --- admin/uploaduser.php | 10 +- admin/user.php | 150 ++--------- admin/user/lib.php | 53 ++++ admin/user/user_bulk.php | 146 +++++------ admin/user/user_bulk_confirm.php | 62 ++--- admin/user/user_bulk_delete.php | 63 ++--- admin/user/user_bulk_display.php | 139 +++++----- admin/user/user_bulk_form.php | 182 ------------- admin/user/user_bulk_forms.php | 106 ++++++++ admin/user/user_bulk_message.php | 87 ++++--- admin/user/user_message_form.php | 21 +- lang/en_utf8/bulkusers.php | 18 +- lang/en_utf8/filters.php | 49 ++-- lang/en_utf8/help/bulkusers/selectedlist.html | 9 +- lang/en_utf8/help/filters/courserole.html | 5 +- lang/en_utf8/help/filters/date.html | 2 +- lang/en_utf8/help/filters/radios.html | 3 - lang/en_utf8/help/filters/simpleselect.html | 2 + lang/en_utf8/moodle.php | 1 + lib/datalib.php | 12 +- user/filters/courserole.php | 153 ++++++----- user/filters/date.php | 151 ++++++----- user/filters/globalrole.php | 75 +++--- user/filters/lib.php | 239 +++++++++++++++--- user/filters/profilefield.php | 232 ++++++++--------- user/filters/radios.php | 80 ------ user/filters/select.php | 124 +++++---- user/filters/simpleselect.php | 88 +++++++ user/filters/text.php | 176 ++++++------- user/filters/user_filter_form.php | 178 ------------- user/filters/user_filter_forms.php | 69 +++++ user/filters/yesno.php | 13 +- 32 files changed, 1374 insertions(+), 1324 deletions(-) create mode 100644 admin/user/lib.php delete mode 100644 admin/user/user_bulk_form.php create mode 100644 admin/user/user_bulk_forms.php delete mode 100644 lang/en_utf8/help/filters/radios.html create mode 100644 lang/en_utf8/help/filters/simpleselect.html delete mode 100644 user/filters/radios.php create mode 100644 user/filters/simpleselect.php delete mode 100644 user/filters/user_filter_form.php create mode 100644 user/filters/user_filter_forms.php diff --git a/admin/uploaduser.php b/admin/uploaduser.php index 04c7878ca5..ca4c886d7f 100755 --- a/admin/uploaduser.php +++ b/admin/uploaduser.php @@ -169,7 +169,7 @@ if ($formdata = $mform->is_cancelled()) { // clear bilk selection if ($bulk) { - $SESSION->bulk_susers = array(); + $SESSION->bulk_users = array(); } // init csv import helper @@ -483,8 +483,8 @@ if ($formdata = $mform->is_cancelled()) { } if ($bulk == 2 or $bulk == 3) { - if (!in_array($user->id, $SESSION->bulk_susers)) { - $SESSION->bulk_susers[] = $user->id; + if (!in_array($user->id, $SESSION->bulk_users)) { + $SESSION->bulk_users[] = $user->id; } } @@ -547,8 +547,8 @@ if ($formdata = $mform->is_cancelled()) { get_context_instance(CONTEXT_PERSONAL, $user->id); if ($bulk == 1 or $bulk == 3) { - if (!in_array($user->id, $SESSION->bulk_susers)) { - $SESSION->bulk_susers[] = $user->id; + if (!in_array($user->id, $SESSION->bulk_users)) { + $SESSION->bulk_users[] = $user->id; } } } diff --git a/admin/user.php b/admin/user.php index a68303d912..0b975f030d 100644 --- a/admin/user.php +++ b/admin/user.php @@ -2,6 +2,7 @@ require_once('../config.php'); require_once($CFG->libdir.'/adminlib.php'); + require_once($CFG->dirroot.'/user/filters/lib.php'); $delete = optional_param('delete', 0, PARAM_INT); $confirm = optional_param('confirm', '', PARAM_ALPHANUM); //md5 confirmation hash @@ -10,9 +11,6 @@ $dir = optional_param('dir', 'ASC', PARAM_ALPHA); $page = optional_param('page', 0, PARAM_INT); $perpage = optional_param('perpage', 30, PARAM_INT); // how many per page - $search = trim(optional_param('search', '', PARAM_RAW)); - $lastinitial = optional_param('lastinitial', '', PARAM_CLEAN); // only show students with this last initial - $firstinitial = optional_param('firstinitial', '', PARAM_CLEAN); // only show students with this first initial $ru = optional_param('ru', '2', PARAM_INT); // show remote users $lu = optional_param('lu', '2', PARAM_INT); // show local users $acl = optional_param('acl', '0', PARAM_INT); // id of user to tweak mnet ACL (requires $access) @@ -20,37 +18,7 @@ admin_externalpage_setup('editusers'); - // Let's see if we have *any* mnet users. Just ask for a single record - $mnet_users = get_records_select('user', " auth='mnet' AND mnethostid != '{$CFG->mnet_localhost_id}' ", '', '*', '0', '1'); - if(is_array($mnet_users) && count($mnet_users) > 0) { - $mnet_auth_users = true; - } else { - $mnet_auth_users = false; - } - - if($mnet_auth_users) { - // Determine which users we are looking at (local, remote, or both). Start with both. - if (!isset($_SESSION['admin-user-remoteusers'])) { - $_SESSION['admin-user-remoteusers'] = 1; - $_SESSION['admin-user-localusers'] = 1; - } - if ($ru == 0 or $ru == 1) { - $_SESSION['admin-user-remoteusers'] = $ru; - } - if ($lu == 0 or $lu == 1) { - $_SESSION['admin-user-localusers'] = $lu; - } - $remoteusers = $_SESSION['admin-user-remoteusers']; - $localusers = $_SESSION['admin-user-localusers']; - - // if neither remote nor local, set to sensible local only - if (!$remoteusers and !$localusers) { - $_SESSION['admin-user-localusers'] = 1; - $localusers = 1; - } - } - - $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID); + $sitecontext = get_context_instance(CONTEXT_SYSTEM); $site = get_site(); if (!has_capability('moodle/user:update', $sitecontext) and !has_capability('moodle/user:delete', $sitecontext)) { @@ -60,7 +28,6 @@ $stredit = get_string('edit'); $strdelete = get_string('delete'); $strdeletecheck = get_string('deletecheck'); - $strsearch = get_string('search'); $strshowallusers = get_string('showallusers'); if (empty($CFG->loginhttps)) { @@ -151,6 +118,9 @@ . "' access now set to '$accessctrl'."); } + // create the user filter form + $ufiltering = new user_filtering(); + // Carry on with the user listing $columns = array("firstname", "lastname", "email", "city", "country", "lastaccess"); @@ -174,28 +144,19 @@ $columnicon = " pixpath/t/$columnicon.gif\" alt=\"\" />"; } - $$column = "".$string[$column]."$columnicon"; + $$column = "".$string[$column]."$columnicon"; } if ($sort == "name") { $sort = "firstname"; } - - // tell the query which users we are looking at (local, remote, or both) - $remotewhere = ''; - if($mnet_auth_users && ($localusers XOR $remoteusers)) { - if ($localusers) { - $remotewhere .= " and mnethostid = {$CFG->mnet_localhost_id} "; - } else { - $remotewhere .= " and mnethostid <> {$CFG->mnet_localhost_id} "; - } - } - - $users = get_users_listing($sort, $dir, $page*$perpage, $perpage, $search, $firstinitial, $lastinitial, $remotewhere); + + $extrasql = $ufiltering->get_sql_filter(); + $users = get_users_listing($sort, $dir, $page*$perpage, $perpage, '', '', '', $extrasql); $usercount = get_users(false); - $usersearchcount = get_users(false, $search, true, "", "", $firstinitial, $lastinitial); + $usersearchcount = get_users(false, '', true, "", "", '', '', '', '', '*', $extrasql); - if ($search or $firstinitial or $lastinitial) { + if ($extrasql !== '') { print_heading("$usersearchcount / $usercount ".get_string('users')); $usercount = $usersearchcount; } else { @@ -205,65 +166,15 @@ $alphabet = explode(',', get_string('alphabet')); $strall = get_string('all'); - - /// Bar of first initials - - echo "

"; - echo get_string("firstname")." : "; - if ($firstinitial) { - echo " $strall "; - } else { - echo " $strall "; - } - foreach ($alphabet as $letter) { - if ($letter == $firstinitial) { - echo " $letter "; - } else { - echo " $letter "; - } - } - echo "
"; - - /// Bar of last initials - - echo get_string("lastname")." : "; - if ($lastinitial) { - echo " $strall "; - } else { - echo " $strall "; - } - foreach ($alphabet as $letter) { - if ($letter == $lastinitial) { - echo " $letter "; - } else { - echo " $letter "; - } - } - echo "

"; - print_paging_bar($usercount, $page, $perpage, - "user.php?sort=$sort&dir=$dir&perpage=$perpage&firstinitial=$firstinitial&lastinitial=$lastinitial&search=".urlencode(stripslashes($search))."&"); + "user.php?sort=$sort&dir=$dir&perpage=$perpage&"); flush(); if (!$users) { $match = array(); - if ($search !== '') { - $match[] = s($search); - } - if ($firstinitial) { - $match[] = get_string('firstname').": $firstinitial"."___"; - } - if ($lastinitial) { - $match[] = get_string('lastname').": $lastinitial"."___"; - } - $matchstring = implode(", ", $match); - print_heading(get_string('nousersmatching', '', $matchstring)); + print_heading(get_string('nousersfound')); $table = NULL; @@ -367,34 +278,9 @@ } } - if($mnet_auth_users) { - echo "

"; - if ($localusers == 1 && $remoteusers == 1) { - echo ''.get_string('hidelocal','mnet').' | '; - } elseif ($localusers == 0) { - echo ''.get_string('showlocal','mnet').' | '; - } else { - echo get_string('hidelocal','mnet').' | '; - } - if ($localusers == 1 && $remoteusers == 1) { - echo ''.get_string('hideremote','mnet').''; - } elseif ($remoteusers == 0) { - echo ''.get_string('showremote','mnet').''; - } else { - echo get_string('hideremote','mnet'); - } - echo "

"; - } - - echo "
"; - echo "
"; - echo ""; - echo ""; - if ($search) { - echo ""; - } - echo "
"; - echo "
"; + // add filters + $ufiltering->display_add(); + $ufiltering->display_active(); if (has_capability('moodle/user:create', $sitecontext)) { print_heading(''.get_string('addnewuser').''); @@ -402,14 +288,12 @@ if (!empty($table)) { print_table($table); print_paging_bar($usercount, $page, $perpage, - "user.php?sort=$sort&dir=$dir&perpage=$perpage". - "&firstinitial=$firstinitial&lastinitial=$lastinitial&search=".urlencode(stripslashes($search))."&"); + "user.php?sort=$sort&dir=$dir&perpage=$perpage&"); if (has_capability('moodle/user:create', $sitecontext)) { print_heading(''.get_string('addnewuser').''); } } - admin_externalpage_print_footer(); diff --git a/admin/user/lib.php b/admin/user/lib.php new file mode 100644 index 0000000000..28c2e33ee2 --- /dev/null +++ b/admin/user/lib.php @@ -0,0 +1,53 @@ +dirroot.'/user/filters/lib.php'); + +if (!defined('MAX_BULK_USERS')) { + define('MAX_BULK_USERS', 2000); +} + +function add_selection_all($ufiltering) { + global $SESSION; + + $guest = get_guest(); + $sqlwhere = $ufiltering->get_sql_filter("id<>{$guest->id} AND deleted <> 1"); + + if ($rs = get_recordset_select('user', $sqlwhere, 'fullname', 'id,'.sql_fullname().' AS fullname')) { + while ($user = rs_fetch_next_record($rs)) { + if (!in_array($user->id, $SESSION->bulk_users)) { + $SESSION->bulk_users[] = $user->id; + } + } + rs_close($rs); + } +} + +function get_selection_data($ufiltering) { + global $SESSION; + + // get the SQL filter + $guest = get_guest(); + $sqlwhere = $ufiltering->get_sql_filter("id<>{$guest->id} AND deleted <> 1"); + + $total = count_records_select('user', "id<>{$guest->id} AND deleted <> 1"); + $acount = count_records_select('user', $sqlwhere); + $scount = count($SESSION->bulk_users); + + $userlist = array('acount'=>$acount, 'scount'=>$scount, 'ausers'=>false, 'susers'=>false, 'total'=>$total); + $userlist['ausers'] = get_records_select_menu('user', $sqlwhere, 'fullname', 'id,'.sql_fullname().' AS fullname', 0, MAX_BULK_USERS); + + if ($scount) { + if ($scount < MAX_BULK_USERS) { + $in = implode(',', $SESSION->bulk_users); + } else { + $bulkusers = array_slice($SESSION->bulk_users, 0, MAX_BULK_USERS); + $in = implode(',', $bulkusers); + } + $userlist['susers'] = get_records_select_menu('user', "id IN ($in)", 'fullname', 'id,'.sql_fullname().' AS fullname'); + } + + return $userlist; +} + + +?> \ No newline at end of file diff --git a/admin/user/user_bulk.php b/admin/user/user_bulk.php index 1e00b86b58..af89c050a0 100755 --- a/admin/user/user_bulk.php +++ b/admin/user/user_bulk.php @@ -1,82 +1,84 @@ libdir.'/adminlib.php'); - require_once($CFG->libdir.'/dmllib.php'); - require_once($CFG->dirroot.'/user/filters/text.php'); - require_once($CFG->dirroot.'/user/filters/date.php'); - require_once($CFG->dirroot.'/user/filters/select.php'); - require_once($CFG->dirroot.'/user/filters/courserole.php'); - require_once($CFG->dirroot.'/user/filters/globalrole.php'); - require_once($CFG->dirroot.'/user/filters/profilefield.php'); - require_once($CFG->dirroot.'/user/filters/yesno.php'); +require_once('../../config.php'); +require_once($CFG->libdir.'/adminlib.php'); +require_once($CFG->dirroot.'/'.$CFG->admin.'/user/lib.php'); +require_once($CFG->dirroot.'/'.$CFG->admin.'/user/user_bulk_forms.php'); - require_once($CFG->dirroot.'/admin/user/user_bulk_form.php'); - define("MAX_USERS_PER_PAGE", 5000); +admin_externalpage_setup('userbulk'); - $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID); +if (!isset($SESSION->bulk_users)) { + $SESSION->bulk_users = array(); +} +// create the user filter form +$ufiltering = new user_filtering(); - // array of bulk operations - $actions = array(); - $actions[1] = get_string('confirm'); - if (has_capability('moodle/site:readallmessages', $sitecontext) && !empty($CFG->messaging)) { - $actions[2] = get_string('messageselectadd'); - } - $actions[3] = get_string('delete'); - $actions[4] = get_string('displayonpage'); - // create the bulk operations form - $user_bulk_form =& new user_bulk_form(null, $actions); +// array of bulk operations +// create the bulk operations form +$action_form = new user_bulk_action_form(); +if ($data = $action_form->get_data(false)) { // check if an action should be performed and do so - switch ($user_bulk_form->getAction()) { - case 1: - redirect($CFG->wwwroot . '/admin/user/user_bulk_confirm.php'); - break; - case 2: - redirect($CFG->wwwroot . '/admin/user/user_bulk_message.php'); - break; - case 3: - redirect($CFG->wwwroot . '/admin/user/user_bulk_delete.php'); - break; - case 4: - redirect($CFG->wwwroot . '/admin/user/user_bulk_display.php'); - break; - default: - break; + switch ($data->action) { + case 1: redirect($CFG->wwwroot.'/'.$CFG->admin.'/user/user_bulk_confirm.php'); + case 2: redirect($CFG->wwwroot.'/'.$CFG->admin.'/user/user_bulk_message.php'); + case 3: redirect($CFG->wwwroot.'/'.$CFG->admin.'/user/user_bulk_delete.php'); + case 4: redirect($CFG->wwwroot.'/'.$CFG->admin.'/user/user_bulk_display.php'); } +} + +$user_bulk_form = new user_bulk_form(null, get_selection_data($ufiltering)); + +if ($data = $user_bulk_form->get_data(false)) { + if (!empty($data->addall)) { + add_selection_all($ufiltering); + + } else if (!empty($data->addsel)) { + if (!empty($data->ausers)) { + if (in_array(0, $data->ausers)) { + add_selection_all($ufiltering); + } else { + foreach($data->ausers as $userid) { + if ($userid == -1) { + continue; + } + if (!in_array($userid, $SESSION->bulk_users)) { + $SESSION->bulk_users[] = $userid; + } + } + } + } + + } else if (!empty($data->removeall)) { + $SESSION->bulk_users= array(); - // prepare user filter types - $filters[] = new user_filter_text('username', get_string('username'), 'username'); - $filters[] = new user_filter_text('realname', get_string('fullname'), sql_fullname()); - $filters[] = new user_filter_text('email', get_string('email'), 'email'); - $filters[] = new user_filter_text('city', get_string('city'), 'city'); - $filters[] = new user_filter_select('country', get_string('country'), 'country', get_list_of_countries()); - $filters[] = new user_filter_yesno('confirmed', get_string('confirm'), 'confirmed'); - $filters[] = new user_filter_profilefield('profile', get_string('profile')); - $filters[] = new user_filter_courserole('course', get_string('courserole', 'filters')); - $filters[] = new user_filter_globalrole('system', get_string('globalrole', 'role')); - $filters[] = new user_filter_date('date', get_string('date'), 'lastaccess', array('lastlogin'=> get_string('lastlogin'), 'firstaccess' => get_string('firstaccess', 'filters'), 'lastaccess' => get_string('lastaccess'), 'timemodified' => get_string('lastmodified'))); - - // create the user filter form - $user_filter_form =& new user_filter_form(null, $filters); - - // do output - admin_externalpage_setup('userbulk'); - admin_externalpage_print_header(); - - // put the user filter form first - $user_filter_form->display(); - // get the SQL filter - $where =& $user_filter_form->getSQLFilter('id<>1 AND deleted <> 1'); - $ausercount = count_records_select('user', $where); - // limit the number of options - $comment = null; - if($ausercount <= MAX_USERS_PER_PAGE) { - $user_bulk_form->setAvailableUsersSQL($where); - } else { - $comment = get_string('toomanytoshow'); + } else if (!empty($data->removesel)) { + if (!empty($data->susers)) { + if (in_array(0, $data->susers)) { + $SESSION->bulk_users= array(); + } else { + foreach($data->susers as $userid) { + if ($userid == -1) { + continue; + } + unset($SESSION->bulk_users[$userid]); + } + } + } } - $user_bulk_form->setUserCount($ausercount, $comment); - // display the bulk user form - $user_bulk_form->display(); - admin_externalpage_print_footer(); + + // reset the form selections + unset($_POST); + $user_bulk_form = new user_bulk_form(null, get_selection_data($ufiltering)); +} +// do output +admin_externalpage_print_header(); + +$ufiltering->display_add(); +$ufiltering->display_active(); + +$user_bulk_form->display(); +$action_form->display(); + +admin_externalpage_print_footer(); + ?> diff --git a/admin/user/user_bulk_confirm.php b/admin/user/user_bulk_confirm.php index eef6929dd5..fe0a8bfbaa 100755 --- a/admin/user/user_bulk_confirm.php +++ b/admin/user/user_bulk_confirm.php @@ -6,46 +6,48 @@ require_once('../../config.php'); require_once($CFG->libdir.'/adminlib.php'); -$confirm = optional_param('confirm', 0, PARAM_BOOL); -$sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID); -require_capability('moodle/user:update', $sitecontext); - -// clean-up users list -$primaryadmin = get_admin(); -$userlist = array(); -foreach ($SESSION->bulk_susers as $k => $v) { - $user = get_record('user', 'id', $v, null, null, null, null, 'id,firstname,lastname,username,secret,confirmed,mnethostid,auth'); - if (!empty($user) && $user->id != $primaryadmin->id && !$user->confirmed && !is_mnet_remote_user($user)) { - $userlist[$k] = $user; - } -} +$confirm = optional_param('confirm', 0, PARAM_BOOL); + +admin_externalpage_setup('userbulk'); +require_capability('moodle/user:update', get_context_instance(CONTEXT_SYSTEM)); -if (empty($userlist)) { - redirect($CFG->wwwroot . '/admin/user/user_bulk.php'); +$return = $CFG->wwwroot.'/'.$CFG->admin.'/user/user_bulk.php'; + +if (empty($SESSION->bulk_users)) { + redirect($return); } -admin_externalpage_setup('userbulk'); admin_externalpage_print_header(); -if (empty($confirm)) { - $usernames = array(); - foreach ($userlist as $user) { - $usernames[] =& fullname($user, true); +//TODO: add support for large number of users + +if ($confirm and confirm_sesskey()) { + $in = implode(',', $SESSION->bulk_users); + if ($rs = get_recordset_select('user', "id IN ($in)", '', 'id, username, secret, confirmed, auth, firstname, lastname')) { + while ($user = rs_fetch_next_record($rs)) { + if ($user->confirmed) { + continue; + } + $auth = get_auth_plugin($user->auth); + $result = $auth->user_confirm(addslashes($user->username), addslashes($user->secret)); + if ($result != AUTH_CONFIRM_OK && $result != AUTH_CONFIRM_ALREADY) { + notify(get_string('usernotconfirmed', '', fullname($user, true))); + } + } + rs_close($rs); } - $usernames = implode(', ', $usernames); + redirect($return, get_string('changessaved')); + +} else { + $in = implode(',', $SESSION->bulk_users); + $userlist = get_records_select_menu('user', "id IN ($in)", 'fullname', 'id,'.sql_fullname().' AS fullname'); + $usernames = implode(', ', $userlist); + $optionsyes = array(); $optionsyes['confirm'] = 1; $optionsyes['sesskey'] = sesskey(); print_heading(get_string('confirmation', 'admin')); notice_yesno(get_string('confirmcheckfull', '', $usernames), 'user_bulk_confirm.php', 'user_bulk.php', $optionsyes, NULL, 'post', 'get'); -} else { - foreach ($userlist as $k => $user) { - $auth = get_auth_plugin($user->auth); - $result = $auth->user_confirm(addslashes($user->username), addslashes($user->secret)); - if ($result != AUTH_CONFIRM_OK && $result != AUTH_CONFIRM_ALREADY) { - notify(get_string('usernotconfirmed', '', fullname($user, true))); - } - } - redirect($CFG->wwwroot . '/admin/user/user_bulk.php', get_string('changessaved')); } + admin_externalpage_print_footer(); ?> \ No newline at end of file diff --git a/admin/user/user_bulk_delete.php b/admin/user/user_bulk_delete.php index 513d54054d..413c833078 100755 --- a/admin/user/user_bulk_delete.php +++ b/admin/user/user_bulk_delete.php @@ -6,46 +6,47 @@ require_once('../../config.php'); require_once($CFG->libdir.'/adminlib.php'); -$confirm = optional_param('confirm', 0, PARAM_BOOL); -$sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID); - -require_capability('moodle/user:delete', $sitecontext); - -// clean-up users list -$primaryadmin = get_admin(); -$userlist = array(); -foreach ($SESSION->bulk_susers as $k => $v) { - $user = get_record('user', 'id', $v, null, null, null, null, 'id,firstname,lastname,email,auth'); - if (!empty($user) && $user->id != $primaryadmin->id) { - $userlist[$k] = $user; - } -} +$confirm = optional_param('confirm', 0, PARAM_BOOL); + +admin_externalpage_setup('userbulk'); +require_capability('moodle/user:delete', get_context_instance(CONTEXT_SYSTEM)); -if (empty($userlist)) { - redirect($CFG->wwwroot . '/admin/user/user_bulk.php'); +$return = $CFG->wwwroot.'/'.$CFG->admin.'/user/user_bulk.php'; + +if (empty($SESSION->bulk_users)) { + redirect($return); } -admin_externalpage_setup('userbulk'); admin_externalpage_print_header(); -if (empty($confirm)) { - $usernames = array(); - foreach ($userlist as $user) { - $usernames[] =& fullname($user, true); + +//TODO: add support for large number of users + +if ($confirm and confirm_sesskey()) { + $primaryadmin = get_admin(); + + $in = implode(',', $SESSION->bulk_users); + if ($rs = get_recordset_select('user', "id IN ($in)")) { + while ($user = rs_fetch_next_record($rs)) { + if ($primaryadmin->id != $user->id and $USER->id != $user->id and delete_user($user)) { + unset($SESSION->bulk_users[$user->id]); + } else { + notify(get_string('deletednot', '', fullname($user, true))); + } + } + rs_close($rs); } - $usernames = implode(', ', $usernames); + redirect($return, get_string('changessaved')); + +} else { + $in = implode(',', $SESSION->bulk_users); + $userlist = get_records_select_menu('user', "id IN ($in)", 'fullname', 'id,'.sql_fullname().' AS fullname'); + $usernames = implode(', ', $userlist); + $optionsyes = array(); $optionsyes['confirm'] = 1; $optionsyes['sesskey'] = sesskey(); print_heading(get_string('confirmation', 'admin')); notice_yesno(get_string('deletecheckfull', '', $usernames), 'user_bulk_delete.php', 'user_bulk.php', $optionsyes, NULL, 'post', 'get'); -} else { - foreach ($userlist as $k => $user) { - if (delete_user($user)) { - unset($SESSION->bulk_susers[$k]); - } else { - notify(get_string('deletednot', '', fullname($user, true))); - } - } - redirect($CFG->wwwroot . '/admin/user/user_bulk.php', get_string('changessaved')); } + admin_externalpage_print_footer(); ?> diff --git a/admin/user/user_bulk_display.php b/admin/user/user_bulk_display.php index 7504ba9a5d..97d36f3f47 100755 --- a/admin/user/user_bulk_display.php +++ b/admin/user/user_bulk_display.php @@ -1,76 +1,81 @@ libdir.'/adminlib.php'); +require_once('../../config.php'); +require_once($CFG->libdir.'/adminlib.php'); - if(empty($SESSION->bulk_susers)) { - redirect($CFG->wwwroot . '/admin/user/user_bulk.php'); - } - $users = $SESSION->bulk_susers; - $usertotal = get_users(false); - $usercount = count($users); - - $sort = optional_param('sort', 'fullname', PARAM_ALPHA); - $dir = optional_param('dir', 'asc', PARAM_ALPHA); - - $strnever = get_string('never'); - $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID); - $site = get_site(); - - admin_externalpage_setup('userbulk'); - admin_externalpage_print_header(); - - $countries =& get_list_of_countries(); - foreach ($users as $key => $id) { - $user =& get_record('user', 'id', $id, null, null, null, null, 'id,firstname,lastname,username,email,country,lastaccess,city'); - $user->fullname = fullname($user, true); - $user->country = @$countries[$user->country]; - unset($user->firstname); - unset($user->lastname); - $users[$key] = $user; - } - unset($countries); - - // Need to sort by data - function sort_compare($a, $b) { - global $sort, $dir; - if($sort == 'lastaccess') { - $rez = $b->lastaccess - $a->lastaccess; - } else { - $rez = strcasecmp(@$a->$sort, @$b->$sort); - } - return $dir == 'desc' ? -$rez : $rez; - } - usort($users, 'sort_compare'); - - $table->width = "95%"; - $columns = array('fullname', 'username', 'email', 'city', 'country', 'lastaccess'); - foreach ($columns as $column) { - $strtitle = get_string($column); - if ($sort != $column) { - $columnicon = ''; - $columndir = 'asc'; - } else { - $columndir = $dir == 'asc' ? 'desc' : 'asc'; - $columnicon = ' '; - } - $table->head[] = '' .$strtitle . '' . $columnicon; - $table->align[] = 'left'; +$sort = optional_param('sort', 'fullname', PARAM_ALPHA); +$dir = optional_param('dir', 'asc', PARAM_ALPHA); + +admin_externalpage_setup('userbulk'); + +$return = $CFG->wwwroot.'/'.$CFG->admin.'/user/user_bulk.php'; + +if (empty($SESSION->bulk_users)) { + redirect($return); +} + +$users = $SESSION->bulk_users; +$usertotal = get_users(false); +$usercount = count($users); + +$strnever = get_string('never'); + +admin_externalpage_print_header(); + +$countries = get_list_of_countries(); + +foreach ($users as $key => $id) { + $user = get_record('user', 'id', $id, null, null, null, null, 'id, firstname, lastname, username, email, country, lastaccess, city'); + $user->fullname = fullname($user, true); + $user->country = @$countries[$user->country]; + unset($user->firstname); + unset($user->lastname); + $users[$key] = $user; +} +unset($countries); + +// Need to sort by date +function sort_compare($a, $b) { + global $sort, $dir; + if($sort == 'lastaccess') { + $rez = $b->lastaccess - $a->lastaccess; + } else { + $rez = strcasecmp(@$a->$sort, @$b->$sort); } + return $dir == 'desc' ? -$rez : $rez; +} +usort($users, 'sort_compare'); - foreach($users as $user) { - $table->data[] = array ( - '' . $user->fullname .'', - $user->username, - $user->email, - $user->city, - $user->country, - $user->lastaccess ? format_time(time() - $user->lastaccess) : $strnever - ); +$table->width = "95%"; +$columns = array('fullname', /*'username', */'email', 'city', 'country', 'lastaccess'); +foreach ($columns as $column) { + $strtitle = get_string($column); + if ($sort != $column) { + $columnicon = ''; + $columndir = 'asc'; + } else { + $columndir = $dir == 'asc' ? 'desc' : 'asc'; + $columnicon = ' '; } + $table->head[] = ''.$strtitle.''.$columnicon; + $table->align[] = 'left'; +} + +foreach($users as $user) { + $table->data[] = array ( + ''.$user->fullname.'', +// $user->username, + $user->email, + $user->city, + $user->country, + $user->lastaccess ? format_time(time() - $user->lastaccess) : $strnever + ); +} + +print_heading("$usercount / $usertotal ".get_string('users')); +print_table($table); - print_heading("$usercount / $usertotal ".get_string('users')); - print_table($table); +print_continue($return); - admin_externalpage_print_footer(); +admin_externalpage_print_footer(); ?> \ No newline at end of file diff --git a/admin/user/user_bulk_form.php b/admin/user/user_bulk_form.php deleted file mode 100644 index 6dd37892fb..0000000000 --- a/admin/user/user_bulk_form.php +++ /dev/null @@ -1,182 +0,0 @@ -libdir.'/formslib.php'); -require_once($CFG->libdir . '/datalib.php'); - -class user_bulk_form extends moodleform { - /** - * Quickform select object for the available users. - */ - var $ausers; - /** - * Quickform select object for the selected users. - */ - var $susers; - // form definition - function definition() { - $mform =& $this->_form; - $mform->addElement('header', 'users', get_string('usersinlist', 'bulkusers')); - - $this->ausers =& $mform->createElement('select', 'ausers', get_string('available', 'bulkusers'), null, 'size="15"'); - $this->ausers->setMultiple(true); - $this->susers =& $mform->createElement('select', 'susers', get_string('selected', 'bulkusers'), null, 'size="15"'); - $this->susers->setMultiple(true); - - $objs = array(); - $objs[] = &$this->ausers; - $objs[] = &$this->susers; - - $grp =& $mform->addElement('group', 'usersgrp', get_string('users'), $objs, ' ', false); - $grp->setHelpButton(array('lists','','bulkusers')); - - $mform->addElement('static', 'comment'); - - $objs = array(); - $objs[] =& $mform->createElement('submit', 'addone', get_string('addsel', 'bulkusers')); - $objs[] =& $mform->createElement('submit', 'addall', get_string('addall', 'bulkusers')); - $objs[] =& $mform->createElement('submit', 'deletesel', get_string('deletesel', 'bulkusers')); - $objs[] =& $mform->createElement('submit', 'deleteall', get_string('deleteall', 'bulkusers')); - $grp =& $mform->addElement('group', 'buttonsgrp', get_string('selectedlist', 'bulkusers'), $objs, array(' ', '
'), false); - $grp->setHelpButton(array('selectedlist','','bulkusers')); - - $objs = array(); - $objs[] =& $mform->createElement('select', 'action', get_string('withselected'), @$this->_customdata); - $objs[] =& $mform->createElement('submit', 'doaction', get_string('go'));; - $mform->addElement('group', 'actionsgrp', get_string('withselectedusers'), $objs, ' ', false); - - $renderer =& $mform->defaultRenderer(); - $template = ' {element}'; - $renderer->setGroupElementTemplate($template, 'usersgrp'); - } - - function setUserCount($count=-1, $comment=null) { - global $SESSION; - if($count < 0) { - $count = count($SESSION->bulk_ausers); - } - $obj =& $this->_form->getElement('comment'); - $obj->setLabel($comment); - $obj->setText(get_string('usersfound', 'bulkusers', $count) . ' ' .get_string('usersselected', 'bulkusers', count(@$SESSION->bulk_susers))); - } - - function definition_after_data() { - global $SESSION; - $this->_updateSelection($this->get_data()); - $this->setSelectedUsers($SESSION->bulk_susers); - if(empty($SESSION->bulk_susers)) { - $this->_form->removeElement('actionsgrp'); - } - //$this->setUserCount(); - } - - /** - * Updates the user selection based on the data submited to the form. - * @param object $data object with data received by the form - */ - function _updateSelection($data) { - global $SESSION; - if(!is_array(@$SESSION->bulk_susers)) { - $SESSION->bulk_susers = array(); - } - // if the forms was not submited, then quit - if(is_null($data)){ - return; - } - if(@$data->addall) { - if(!empty($SESSION->bulk_ausers)) { - $SESSION->bulk_susers = array_merge($SESSION->bulk_susers, $SESSION->bulk_ausers); - } - } else if(@$data->addone) { - if(!empty($data->ausers)) { - $SESSION->bulk_susers = array_merge($SESSION->bulk_susers, array_values($data->ausers)); - } - } else if(@$data->deletesel) { - if(!empty($data->susers)) { - $SESSION->bulk_susers = array_diff($SESSION->bulk_susers, array_values($data->susers)); - } - } else if(@$data->deleteall) { - $SESSION->bulk_susers = array(); - } - $SESSION->bulk_susers = array_unique($SESSION->bulk_susers); - } - - /** - * Sets the available users list, based on their ids - * @param array $ausers array of user ids - */ - function setAvailableUsers($ausers) { - $sqlwhere = null; - if(!empty($ausers)) { - $sqlwhere = 'id IN (' . implode(',', $ausers) . ')'; - } - $this->setAvailableUsersSQL($sqlwhere); - } - - /** - * Sets the available users list, based on a SQL where condition - * @param string $sqlwhere filter for the users - */ - function setAvailableUsersSQL($sqlwhere=null) { - global $SESSION; - if(is_null($sqlwhere) || ($users =& $this->getUserData($sqlwhere))===false) { - $users = array(); - } - $SESSION->bulk_ausers =& array_keys($users); - $this->ausers->load($users); - } - - /** - * Sets the selected users list, based on their ids - * @param array $ausers array of user ids - */ - function setSelectedUsers($susers) { - $sqlwhere = null; - if(!empty($susers)) { - $sqlwhere = 'id IN (' . implode(',', $susers) . ')'; - } - $this->setSelectedUsersSQL($sqlwhere); - } - - /** - * Sets the selected users list, based on a SQL where condition - * @param string $sqlwhere filter for the users - */ - function setSelectedUsersSQL($sqlwhere=null) { - global $SESSION; - if(is_null($sqlwhere) || ($users =& $this->getUserData($sqlwhere))===false) { - $users = array(); - } - $SESSION->bulk_susers =& array_keys($users); - $this->susers->load($users); - } - - /** - * Returns information about the users. - * @param string $sqlwhere filter for the users - */ - function getUserData($sqlwhere) { - return get_records_select_menu('user', $sqlwhere, 'fullname', 'id,' . sql_fullname() . ' AS fullname'); - } - - /** - * Returns an array of ids of selected users. - * @return array of selected users' ids - */ - function getSelectedUsers() { - global $SESSION; - return $SESSION->bulk_susers; - } - - /** - * Returns an int code of the action to be performed. - * @return int code of the action or false if no action should be performed - */ - function getAction() { - $data =& $this->get_data(); - if(!$this->is_submitted() || empty($data->doaction)){ - return false; - } - return $data->action; - } -} -?> \ No newline at end of file diff --git a/admin/user/user_bulk_forms.php b/admin/user/user_bulk_forms.php new file mode 100644 index 0000000000..e58611f7c2 --- /dev/null +++ b/admin/user/user_bulk_forms.php @@ -0,0 +1,106 @@ +libdir.'/formslib.php'); +require_once($CFG->libdir.'/datalib.php'); + +class user_bulk_action_form extends moodleform { + function definition() { + global $CFG; + + $mform =& $this->_form; + + $syscontext = get_context_instance(CONTEXT_SYSTEM); + $actions = array(0=>get_string('choose').'...'); + if (has_capability('moodle/user:update', $syscontext)) { + $actions[1] = get_string('confirm'); + } + if (has_capability('moodle/site:readallmessages', $syscontext) && !empty($CFG->messaging)) { + $actions[2] = get_string('messageselectadd'); + } + if (has_capability('moodle/user:delete', $syscontext)) { + $actions[3] = get_string('delete'); + } + $actions[4] = get_string('displayonpage'); + + $objs = array(); + $objs[] =& $mform->createElement('select', 'action', null, $actions); + $objs[] =& $mform->createElement('submit', 'doaction', get_string('go')); + $mform->addElement('group', 'actionsgrp', get_string('withselectedusers'), $objs, ' ', false); + } +} + +class user_bulk_form extends moodleform { + function definition() { + + $mform =& $this->_form; + $acount =& $this->_customdata['acount']; + $scount =& $this->_customdata['scount']; + $ausers =& $this->_customdata['ausers']; + $susers =& $this->_customdata['susers']; + $total =& $this->_customdata['total']; + + $achoices = array(); + $schoices = array(); + + if (is_array($ausers)) { + if ($total == $acount) { + $achoices[0] = get_string('allusers', 'bulkusers', $total); + } else { + $a = new object(); + $a->total = $total; + $a->count = $acount; + $achoices[0] = get_string('allfilteredusers', 'bulkusers', $a); + } + $achoices = $achoices + $ausers; + + if ($acount > MAX_BULK_USERS) { + $achoices[-1] = '...'; + } + + } else { + $achoices[-1] = get_string('nofilteredusers', 'bulkusers', $total); + } + + if (is_array($susers)) { + $a = new object(); + $a->total = $total; + $a->count = $scount; + $schoices[0] = get_string('allselectedusers', 'bulkusers', $a); + $schoices = $schoices + $susers; + + if ($scount > MAX_BULK_USERS) { + $schoices[-1] = '...'; + } + + } else { + $schoices[-1] = get_string('noselectedusers', 'bulkusers'); + } + + $mform->addElement('header', 'users', get_string('usersinlist', 'bulkusers')); + + $objs = array(); + $objs[0] =& $mform->createElement('select', 'ausers', get_string('available', 'bulkusers'), $achoices, 'size="15"'); + $objs[0]->setMultiple(true); + $objs[1] =& $mform->createElement('select', 'susers', get_string('selected', 'bulkusers'), $schoices, 'size="15"'); + $objs[1]->setMultiple(true); + + + $grp =& $mform->addElement('group', 'usersgrp', get_string('users'), $objs, ' ', false); + $grp->setHelpButton(array('lists','','bulkusers')); + + $mform->addElement('static', 'comment'); + + $objs = array(); + $objs[] =& $mform->createElement('submit', 'addsel', get_string('addsel', 'bulkusers')); + $objs[] =& $mform->createElement('submit', 'removesel', get_string('removesel', 'bulkusers')); + $objs[] =& $mform->createElement('submit', 'addall', get_string('addall', 'bulkusers')); + $objs[] =& $mform->createElement('submit', 'removeall', get_string('removeall', 'bulkusers')); + $grp =& $mform->addElement('group', 'buttonsgrp', get_string('selectedlist', 'bulkusers'), $objs, array(' ', '
'), false); + $grp->setHelpButton(array('selectedlist','','bulkusers')); + + $renderer =& $mform->defaultRenderer(); + $template = ' {element}'; + $renderer->setGroupElementTemplate($template, 'usersgrp'); + } +} +?> \ No newline at end of file diff --git a/admin/user/user_bulk_message.php b/admin/user/user_bulk_message.php index 396d08dce0..42751ccca0 100755 --- a/admin/user/user_bulk_message.php +++ b/admin/user/user_bulk_message.php @@ -1,48 +1,71 @@ dirroot.'/message/lib.php'); require_once($CFG->libdir.'/adminlib.php'); +require_once($CFG->dirroot.'/message/lib.php'); +require_once('user_message_form.php'); -require_login(); -require_capability('moodle/site:readallmessages', $sitecontext); -// fix for MDL-10112 -if (empty($CFG->messaging)) { - error("Messaging is disabled on this site"); -} +$msg = optional_param('msg', '', PARAM_CLEAN); +$confirm = optional_param('confirm', 0, PARAM_BOOL); -$users = $SESSION->bulk_susers; -$sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID); +admin_externalpage_setup('userbulk'); +require_capability('moodle/site:readallmessages', get_context_instance(CONTEXT_SYSTEM)); -require_once('user_message_form.php'); -$extradata['userlist'] =& $users; -$noteform =& new user_message_form('user_bulk_message.php', $extradata); -// if no users or action canceled, return to users page -if (empty($users) || $noteform->is_cancelled()) { - redirect($CFG->wwwroot . '/admin/user/user_bulk.php'); +$return = $CFG->wwwroot.'/'.$CFG->admin.'/user/user_bulk.php'; + +if (empty($SESSION->bulk_users)) { + redirect($return); +} + +if (empty($CFG->messaging)) { + error("Messaging is disabled on this site"); } -$formdata =& $noteform->get_data(); -// if we have the message and the command, then send it -if ($noteform->is_submitted() && !empty($formdata->send)) { - if(empty($formdata->messagebody)) { - notify(get_string('allfieldsrequired')); - } else { - foreach ($users as $u) { - if ($user = get_record('user', 'id', $u)) { - message_post_message($USER, $user, addslashes($formdata->messagebody), $formdata->format, 'direct'); - } +//TODO: add support for large number of users + +if ($confirm and !empty($msg) and confirm_sesskey()) { + $in = implode(',', $SESSION->bulk_users); + if ($rs = get_recordset_select('user', "id IN ($in)")) { + while ($user = rs_fetch_next_record($rs)) { + message_post_message($USER, $user, $msg, FORMAT_HTML, 'direct'); } - redirect($CFG->wwwroot . '/admin/user/user_bulk.php'); } + redirect($return); } -admin_externalpage_setup('userbulk'); -admin_externalpage_print_header(); -if ($noteform->is_submitted() && !empty($formdata->preview)) { - echo '

'.get_string('previewhtml').'

'; - echo '
'. format_text(stripslashes($formdata->messagebody),$formdata->format). '
'; +// disable html editor if not enabled in preferences +if (!get_user_preferences('message_usehtmleditor', 0)) { + $CFG->htmleditor = ''; +} + +$msgform = new user_message_form('user_bulk_message.php'); + +if ($msgform->is_cancelled()) { + redirect($return); + +} else if ($formdata = $msgform->get_data(false)) { + $options = new object(); + $options->para = false; + $options->newlines = true; + $options->smiley = false; + + $msg = format_text($formdata->messagebody, $formdata->format, $options); + + $in = implode(',', $SESSION->bulk_users); + $userlist = get_records_select_menu('user', "id IN ($in)", 'fullname', 'id,'.sql_fullname().' AS fullname'); + $usernames = implode(', ', $userlist); + $optionsyes = array(); + $optionsyes['confirm'] = 1; + $optionsyes['sesskey'] = sesskey(); + $optionsyes['msg'] = $msg; + admin_externalpage_print_header(); + print_heading(get_string('confirmation', 'admin')); + print_box($msg, 'boxwidthnarrow boxaligncenter generalbox', 'preview'); + notice_yesno(get_string('confirmmessage', 'bulkusers', $usernames), 'user_bulk_message.php', 'user_bulk.php', $optionsyes, NULL, 'post', 'get'); + admin_externalpage_print_footer(); + die; } -$noteform->display(); +admin_externalpage_print_header(); +$msgform->display(); admin_externalpage_print_footer(); ?> \ No newline at end of file diff --git a/admin/user/user_message_form.php b/admin/user/user_message_form.php index 2d06ea126b..59d00d565b 100644 --- a/admin/user/user_message_form.php +++ b/admin/user/user_message_form.php @@ -5,29 +5,16 @@ require_once($CFG->libdir.'/formslib.php'); class user_message_form extends moodleform { function definition() { - $mform =& $this->_form; + $mform =& $this->_form; $mform->addElement('header', 'general', get_string('message', 'message')); - $mform->addElement('textarea', 'messagebody', get_string('messagebody'), array('rows'=>15, 'cols'=>30)); - $mform->setType('messagebody', PARAM_CLEANHTML); + + $mform->addElement('textarea', 'messagebody', get_string('messagebody'), array('rows'=>15, 'cols'=>60)); $mform->addRule('messagebody', '', 'required', null, 'client'); $mform->setHelpButton('messagebody', array('writing', 'reading', 'questions', 'richtext'), false, 'editorhelpbutton'); - $mform->addElement('format', 'format', get_string('format')); - - $objs = array(); - foreach($this->_customdata['userlist'] as $k=>$u) { - $user = get_record('user', 'id', $u); - $objs[] =& $mform->createElement('static', null, null, ''. fullname($user)); - } - $mform->addElement('group', 'users', 'Users', $objs, '
', false); - $objs = array(); - $objs[] = &$mform->createElement('submit', 'send', 'Send'); - $objs[] = &$mform->createElement('submit', 'preview', 'Preview'); - $objs[] = &$mform->createElement('cancel'); - $mform->addElement('group', 'buttonar', '', $objs, ' ', false); - $mform->closeHeaderBefore('buttonar'); + $this->add_action_buttons(); } } ?> \ No newline at end of file diff --git a/lang/en_utf8/bulkusers.php b/lang/en_utf8/bulkusers.php index 97ba9dea91..da28d16a55 100644 --- a/lang/en_utf8/bulkusers.php +++ b/lang/en_utf8/bulkusers.php @@ -1,11 +1,17 @@ count/$a->total)'; +$string['allselectedusers'] = 'All selected ($a->count/$a->total)'; +$string['allusers'] = 'All users ($a)'; $string['available'] = 'Available'; +$string['addall'] = 'Add all'; +$string['addsel'] = 'Add to selection'; +$string['confirmmessage'] = 'Do you really want to send the message above to all these users?
$a' ; +$string['noselectedusers'] = 'No users selected'; +$string['nofilteredusers'] = 'No users found (0/$a)'; +$string['removesel'] = 'Remove from selection'; +$string['removeall'] = 'Remove all'; $string['selected'] = 'Selected'; $string['selectedlist'] = 'Selected user list...'; $string['usersfound'] = '$a user(s) found.'; -$string['usersselected'] = '$a user(s) selected.'; \ No newline at end of file +$string['usersinlist'] = 'Users in list'; +$string['usersselected'] = '$a user(s) selected.'; diff --git a/lang/en_utf8/filters.php b/lang/en_utf8/filters.php index 1795bb3cf9..1533286daa 100644 --- a/lang/en_utf8/filters.php +++ b/lang/en_utf8/filters.php @@ -1,28 +1,37 @@ label is $a->rolename in $a->coursename from $a->categoryname'; +$string['courserolelabelerror'] = '$a->label error: course $a->coursename does not exist'; +$string['datelabelisafter'] = '$a->label is after $a->after'; +$string['datelabelisbefore'] = '$a->label is before $a->before'; +$string['datelabelisbetween'] = '$a->label is between $a->after and $a->before'; $string['doesnotcontain'] = 'doesn\'t contain'; -$string['isequalto'] = 'is equal to'; -$string['isnotequalto'] = 'isn\'t equal to'; -$string['startswith'] = 'starts with'; $string['endswith'] = 'ends with'; +$string['firstaccess'] = 'First access'; +$string['globalrolelabel'] = '$a->label is $a->value'; +$string['isanyvalue'] = 'is any value'; +$string['isafter'] = 'is after'; +$string['isbefore'] = 'is before'; +$string['isdefined'] = 'is defined'; $string['isempty'] = 'is empty'; -$string['isbefore'] = 'is before $a'; -$string['isafter'] = 'is after $a'; -$string['isbetween'] = 'is between $a[0] and $a[1]'; +$string['isequalto'] = 'is equal to'; +$string['isnotequalto'] = 'isn\'t equal to'; $string['isnotdefined'] = 'isn\'t defined'; -$string['isdefined'] = 'is defined'; -$string['isanyvalue'] = 'is any value'; -$string['categoryrole'] = 'Category role'; -$string['courserole'] = 'Course role'; -$string['firstaccess'] = 'First access'; \ No newline at end of file +$string['newfilter'] = 'New filter'; +$string['profilelabel'] = '$a->label: $a->profile $a->operator $a->value'; +$string['profilelabelnovalue'] = '$a->label: $a->profile $a->operator'; +$string['removeall'] = 'Remove all filters'; +$string['removeselected'] = 'Remove selected'; +$string['selectlabel'] = '$a->label $a->operator $a->value'; +$string['startswith'] = 'starts with'; +$string['textlabel'] = '$a->label $a->operator $a->value'; +$string['textlabelnovalue'] = '$a->label $a->operator'; diff --git a/lang/en_utf8/help/bulkusers/selectedlist.html b/lang/en_utf8/help/bulkusers/selectedlist.html index 606176763b..1a11a5b556 100644 --- a/lang/en_utf8/help/bulkusers/selectedlist.html +++ b/lang/en_utf8/help/bulkusers/selectedlist.html @@ -1,8 +1,9 @@

Selected user list...

diff --git a/lang/en_utf8/help/filters/courserole.html b/lang/en_utf8/help/filters/courserole.html index 84c04a1014..fa07dfc03e 100644 --- a/lang/en_utf8/help/filters/courserole.html +++ b/lang/en_utf8/help/filters/courserole.html @@ -1,3 +1,4 @@

Course role filter

-

This filter allows you to filter users based the role they have assigned in the course specified by its shortname from a specified course category (if the shortname textbox is empty, the category is "any category" and the role is "any role" then the filter is disabled). -

+

This filter allows you to filter users based the role they have assigned in the course +specified by its shortname from a specified course category (if the shortname textbox is empty, +the category is "any category" and the role is "any role" then the filter is not active).

diff --git a/lang/en_utf8/help/filters/date.html b/lang/en_utf8/help/filters/date.html index a6dc65a753..26445fa0a2 100644 --- a/lang/en_utf8/help/filters/date.html +++ b/lang/en_utf8/help/filters/date.html @@ -1,3 +1,3 @@

Date filter

This filter allows you to filter information based on a date value. -Beside the start and end date, depending on the filter settings, you may select the date field used by the filter.

\ No newline at end of file +Beside the start and end date, depending on the filter settings.

\ No newline at end of file diff --git a/lang/en_utf8/help/filters/radios.html b/lang/en_utf8/help/filters/radios.html deleted file mode 100644 index c7d2420f4c..0000000000 --- a/lang/en_utf8/help/filters/radios.html +++ /dev/null @@ -1,3 +0,0 @@ -

Radios filter

-

This filter allows you to filter information based on the option you select. -Depending on the filter settings, the first option might be the "any value" option which disables the filter.

diff --git a/lang/en_utf8/help/filters/simpleselect.html b/lang/en_utf8/help/filters/simpleselect.html new file mode 100644 index 0000000000..baa4fd94e2 --- /dev/null +++ b/lang/en_utf8/help/filters/simpleselect.html @@ -0,0 +1,2 @@ +

Simple select filter

+

This filter allows you to filter information based on a drop down list. This filter does not have any extra options.

diff --git a/lang/en_utf8/moodle.php b/lang/en_utf8/moodle.php index 96a97326ea..c439f607fe 100644 --- a/lang/en_utf8/moodle.php +++ b/lang/en_utf8/moodle.php @@ -1082,6 +1082,7 @@ $string['notincluded'] = 'Not included'; $string['notingroup'] = 'Sorry, but you need to be part of a group to see this activity.'; $string['notpublic'] = 'Not public!'; $string['nousersmatching'] = 'No users matching \'$a\' were found'; +$string['nousersfound'] = 'No users found'; $string['nousersyet'] = 'There are no users yet'; $string['now'] = 'now'; $string['novalidcourses'] = 'No valid courses to be shown'; diff --git a/lib/datalib.php b/lib/datalib.php index 7b21aeda59..f50c4c0817 100644 --- a/lib/datalib.php +++ b/lib/datalib.php @@ -215,7 +215,7 @@ function get_site_users($sort='u.lastaccess DESC', $fields='*', $exceptions='') * @return object|false|int {@link $USER} records unless get is false in which case the integer count of the records found is returned. False is returned if an error is encountered. */ function get_users($get=true, $search='', $confirmed=false, $exceptions='', $sort='firstname ASC', - $firstinitial='', $lastinitial='', $page='', $recordsperpage='', $fields='*') { + $firstinitial='', $lastinitial='', $page='', $recordsperpage='', $fields='*', $extraselect='') { global $CFG; @@ -251,6 +251,10 @@ function get_users($get=true, $search='', $confirmed=false, $exceptions='', $sor $select .= ' AND lastname '. $LIKE .' \''. $lastinitial .'%\''; } + if ($extraselect) { + $select .= " AND $extraselect "; + } + if ($get) { return get_records_select('user', $select, $sort, $fields, $page, $recordsperpage); } else { @@ -277,7 +281,7 @@ function get_users($get=true, $search='', $confirmed=false, $exceptions='', $sor */ function get_users_listing($sort='lastaccess', $dir='ASC', $page=0, $recordsperpage=0, - $search='', $firstinitial='', $lastinitial='', $remotewhere='') { + $search='', $firstinitial='', $lastinitial='', $extraselect='') { global $CFG; @@ -299,7 +303,9 @@ function get_users_listing($sort='lastaccess', $dir='ASC', $page=0, $recordsperp $select .= ' AND lastname '. $LIKE .' \''. $lastinitial .'%\' '; } - $select .= $remotewhere; + if ($extraselect) { + $select .= " AND $extraselect "; + } if ($sort) { $sort = ' ORDER BY '. $sort .' '. $dir; diff --git a/user/filters/courserole.php b/user/filters/courserole.php index f3cde9143b..6c4564f569 100644 --- a/user/filters/courserole.php +++ b/user/filters/courserole.php @@ -1,41 +1,28 @@ dirroot . '/user/filters/lib.php'); +require_once($CFG->dirroot .'/user/filters/lib.php'); /** * User filter based on roles in a course identified by its shortname. */ class user_filter_courserole extends user_filter_type { - /** - * User role (0 = any role) - */ - var $_roleid; - /** - * Course category in which to search the course (0 = all categories). - */ - var $_categoryid; /** * Constructor * @param string $name the name of the filter instance * @param string $label the label of the filter instance - * @param string $field the field used for filtering data - * @param string $value the shortname of the course (used for filtering data) - * @param int $categoryid id of the category - * @param int $roleid id of the role + * @param boolean $advanced advanced form element flag */ - function user_filter_courserole($name, $label, $field='id', $value=null, $categoryid=0, $roleid=0) { - parent::user_filter_type($name, $label, $field, $value); - $this->_roleid = $roleid; - $this->_categoryid = $categoryid; + function user_filter_courserole($name, $label, $advanced) { + parent::user_filter_type($name, $label, $advanced); } - + /** * Returns an array of available roles * @return array of availble roles */ - function getRoles() { - $context =& get_context_instance(CONTEXT_SYSTEM); - $roles =& array_merge(array(0=> get_string('anyrole','filters')), get_assignable_roles($context)); + function get_roles() { + $context = get_context_instance(CONTEXT_SYSTEM); + $roles = array_merge(array(0=> get_string('anyrole','filters')), get_assignable_roles($context)); return $roles; } @@ -43,7 +30,7 @@ class user_filter_courserole extends user_filter_type { * Returns an array of course categories * @return array of course categories */ - function getCourseCategories() { + function get_course_categories() { $displaylist = array(); $parentlist = array(); make_categories_list($displaylist, $parentlist); @@ -56,77 +43,107 @@ class user_filter_courserole extends user_filter_type { */ function setupForm(&$mform) { $objs = array(); - $objs[] =& $mform->createElement('select', $this->_name . '_rl', null, $this->getRoles()); - $objs[] =& $mform->createElement('select', $this->_name . '_ct', null, $this->getCourseCategories()); + $objs[] =& $mform->createElement('select', $this->_name .'_rl', null, $this->get_roles()); + $objs[] =& $mform->createElement('select', $this->_name .'_ct', null, $this->get_course_categories()); $objs[] =& $mform->createElement('text', $this->_name, null); - $grp =& $mform->addElement('group', $this->_name . '_grp', $this->_label, $objs, '', false); - $grp->setHelpButton(array('courserole','','filters')); - $mform->setDefault($this->_name, $this->_value); - $mform->setDefault($this->_name . '_rl', $this->_roleid); - $mform->setDefault($this->_name . '_ct', $this->_categoryid); + $grp =& $mform->addElement('group', $this->_name.'_grp', $this->_label, $objs, '', false); + $grp->setHelpButton(array('courserole', '', 'filters')); + if ($this->_advanced) { + $mform->setAdvanced($this->_name.'_grp'); + } } - + /** * Retrieves data from the form data * @param object $formdata data submited with the form + * @return mixed array filter data or false when filter not set */ - function checkData($formdata) { - $field = $this->_name; - $role = $field . '_rl'; - $category = $field . '_ct'; - $this->_value = (string)@$formdata->$field; - $this->_roleid = (int)@$formdata->$role; - $this->_categoryid = (int)@$formdata->$category; + function check_data($formdata) { + $field = $this->_name; + $role = $field .'_rl'; + $category = $field .'_ct'; + + if (array_key_exists($field, $formdata)) { + if (empty($formdata->$field) and empty($formdata->$role) and empty($formdata->$category)) { + // nothing selected + return false; + } + return array('value' => (string)$formdata->$field, + 'roleid' => (int)$formdata->$role, + 'categoryid' => (int)$formdata->$category); + } + return false; } /** * Returns the condition to be used with SQL where + * @param array $data filter settings * @return string the filtering condition or null if the filter is disabled */ - function getSQLFilter() { + function get_sql_filter($data) { global $CFG; - if(empty($this->_value) && empty($this->_roleid) && empty($this->_categoryid)) { - return null; + $value = addslashes($data['value']); + $roleid = $data['roleid']; + $categoryid = $data['categoryid']; + + if (empty($value) and empty($roleid) and empty($categoryid)) { + return ''; } - $timenow = time(); - $where = 'WHERE b.contextlevel=50 AND timestart<' . $timenow .' AND (timeend=0 OR timeend>'. $timenow . ')'; - if($this->_roleid) { - $where.= ' AND roleid='. $this->_roleid; + + $timenow = round(time(), 100); // rounding - enable sql caching + $where = "b.contextlevel=50 AND a.timestart<$timenow AND (a.timeend=0 OR a.timeend>$timenow)"; + if ($roleid) { + $where .= " AND a.roleid=$roleid"; } - if($this->_categoryid) { - $where .= ' AND category=' . $this->_categoryid; + if ($categoryid) { + $where .= " AND c.category=$categoryid"; } - if($this->_value) { - $where .= ' AND shortname="' . $this->_value . '"'; + if ($value) { + $where .= " AND c.shortname ".sql_ilike()." '$value'"; } - return $this->_field . " IN (SELECT userid FROM {$CFG->prefix}role_assignments a ". - "INNER JOIN {$CFG->prefix}context b ON a.contextid=b.id ". - "INNER JOIN {$CFG->prefix}course c ON b.instanceid=c.id ". - $where . ')'; + return "id IN (SELECT userid + FROM {$CFG->prefix}role_assignments a + INNER JOIN {$CFG->prefix}context b ON a.contextid=b.id + INNER JOIN {$CFG->prefix}course c ON b.instanceid=c.id + WHERE $where)"; } - + /** - * Returns a human friendly description of the filter. - * @return string filter description + * Returns a human friendly description of the filter used as label. + * @param array $data filter settings + * @return string active filter label */ - function getDescription() { - if ($this->_roleid) { - $roles =& $this->getRoles(); - $rolename = '"' . $roles[$this->_roleid]. '"'; + function get_label($data) { + $value = $data['value']; + $roleid = $data['roleid']; + $categoryid = $data['categoryid']; + + $a = new object(); + $a->label = $this->_label; + + if ($roleid) { + $rolename = get_field('role', 'name', 'id', $roleid); + $a->rolename = '"'.format_string($rolename).'"'; } else { - $rolename = get_string('anyrole','filters'); + $a->rolename = get_string('anyrole', 'filters'); } - if ($this->_categoryid) { - $categories=& $this->getCourseCategories(); - $categoryname = '"' . $categories[$this->_categoryid]. '"'; + + if ($categoryid) { + $catname = get_field('course_categories', 'name', 'id', $categoryid); + $a->categoryname = '"'.format_string($catname).'"'; } else { - $categoryname = get_string('anycategory', 'filters'); + $a->categoryname = get_string('anycategory', 'filters'); } - if ($this->_value) { - $coursename = '"' . stripslashes($this->_value). '"'; + + if ($value) { + $a->coursename = '"'.s($value).'"'; + if (!record_exists('course', 'shortname', addslashes($value))) { + return ''.get_string('courserolelabelerror', 'filters', $a).''; + } } else { - $coursename = get_string('anycourse','filters'); + $a->coursename = get_string('anycourse', 'filters'); } - return $this->_label . ' is ' . $rolename. ' in ' . $coursename . ' from ' . $categoryname; + + return get_string('courserolelabel', 'filters', $a); } } diff --git a/user/filters/date.php b/user/filters/date.php index 78f6c34577..98b734bee1 100755 --- a/user/filters/date.php +++ b/user/filters/date.php @@ -1,112 +1,133 @@ dirroot . '/user/filters/lib.php'); +require_once($CFG->dirroot.'/user/filters/lib.php'); /** * Generic filter based on a date. */ class user_filter_date extends user_filter_type { - /** - * the end Unix timestamp (0 if disabled) - */ - var $_value2; /** * the fields available for comparisson */ - var $_fields; + var $_field; + /** * Constructor * @param string $name the name of the filter instance * @param string $label the label of the filter instance - * @param string $field the field used for filtering data - * @param int $start the start Unix timestamp (0 if disabled) - * @param int $end the end Unix timestamp (0 if disabled) + * @param boolean $advanced advanced form element flag + * @param string $field user table filed name */ - function user_filter_date($name, $label, $field, $fields=null, $start=0, $end=0) { - parent::user_filter_type($name, $label, $field, $start); - $this->_value2 = $end; - $this->_fields = $fields; + function user_filter_date($name, $label, $advanced, $field) { + parent::user_filter_type($name, $label, $advanced); + $this->_field = $field; } - + /** * Adds controls specific to this filter in the form. * @param object $mform a MoodleForm object to setup */ function setupForm(&$mform) { $objs = array(); - if(is_array($this->_fields)) { - $objs[] =& $mform->createElement('select', $this->_name . '_fld', null, $this->_fields); - } - $objs[] =& $mform->createElement('checkbox', $this->_name . '_sck', null, get_string('isafter', 'filters')); - $objs[] =& $mform->createElement('date_selector', $this->_name . '_sdt', null); - $objs[] =& $mform->createElement('checkbox', $this->_name . '_eck', null, get_string('isbefore', 'filters')); - $objs[] =& $mform->createElement('date_selector', $this->_name . '_edt', null); - $grp =& $mform->addElement('group', $this->_name . '_grp', $this->_label, $objs, '', false); + + $objs[] =& $mform->createElement('checkbox', $this->_name.'_sck', null, get_string('isafter', 'filters')); + $objs[] =& $mform->createElement('date_selector', $this->_name.'_sdt', null); + $objs[] =& $mform->createElement('checkbox', $this->_name.'_eck', null, get_string('isbefore', 'filters')); + $objs[] =& $mform->createElement('date_selector', $this->_name.'_edt', null); + $grp =& $mform->addElement('group', $this->_name.'_grp', $this->_label, $objs, '', false); $grp->setHelpButton(array('date','','filters')); - $mform->setDefault($this->_name . '_sck', !empty($this->_value)); - $mform->setDefault($this->_name . '_eck', !empty($this->_value2)); - $mform->setDefault($this->_name . '_sdt', $this->_value); - $mform->setDefault($this->_name . '_edt', $this->_value2); - if(is_array($this->_fields)) { - $mform->setDefault($this->_name . '_fld', $this->_field); + + if ($this->_advanced) { + $mform->setAdvanced($this->_name.'_grp'); } - $mform->disabledIf($this->_name . '_sdt', $this->_name . '_sck'); - $mform->disabledIf($this->_name . '_edt', $this->_name . '_eck'); + + $mform->disabledIf($this->_name.'_sdt[day]', $this->_name.'_sck', 'notchecked'); + $mform->disabledIf($this->_name.'_sdt[month]', $this->_name.'_sck', 'notchecked'); + $mform->disabledIf($this->_name.'_sdt[year]', $this->_name.'_sck', 'notchecked'); + $mform->disabledIf($this->_name.'_edt[day]', $this->_name.'_eck', 'notchecked'); + $mform->disabledIf($this->_name.'_edt[month]', $this->_name.'_eck', 'notchecked'); + $mform->disabledIf($this->_name.'_edt[year]', $this->_name.'_eck', 'notchecked'); } - + /** * Retrieves data from the form data * @param object $formdata data submited with the form + * @return mixed array filter data or false when filter not set */ - function checkData($formdata) { - $fld = $this->_name . '_fld'; - $sdt = $this->_name . '_sdt'; - $edt = $this->_name . '_edt'; - $sck = $this->_name . '_sck'; - $eck = $this->_name . '_eck'; - if(@$formdata->$fld) { - $this->_field = @$formdata->$fld; + function check_data($formdata) { + $sck = $this->_name.'_sck'; + $sdt = $this->_name.'_sdt'; + $eck = $this->_name.'_eck'; + $edt = $this->_name.'_edt'; + + if (!array_key_exists($sck, $formdata) and !array_key_exists($eck, $formdata)) { + return false; } - $this->_value = @$formdata->$sck ? (int)@$formdata->$sdt : 0; - $this->_value2 = @$formdata->$eck ? (int)@$formdata->$edt : 0; + + $data = array(); + if (array_key_exists($sck, $formdata)) { + $data['after'] = $formdata->$sdt; + } else { + $data['after'] = 0; + } + if (array_key_exists($eck, $formdata)) { + $data['before'] = $formdata->$edt; + } else { + $data['before'] = 0; + } + return $data; } /** * Returns the condition to be used with SQL where + * @param array $data filter settings * @return string the filtering condition or null if the filter is disabled */ - function getSQLFilter() { - if(empty($this->_value) && empty($this->_value2)) { - return null; + function get_sql_filter($data) { + $after = $data['after']; + $before = $data['before']; + $field = $this->_field; + + if (empty($after) and empty($before)) { + return ''; } - $res = $this->_field . '>0' ; - if($this->_value) { - $res .= ' AND ' . $this->_field . '>=' . $this->_value; + + $res = "$field > 0" ; + + if ($after) { + $res .= " AND $field >= $after"; } - if($this->_value2) { - $res .= ' AND ' . $this->_field . '<=' . $this->_value2; + if ($before) { + $res .= " AND $field <= $before"; } return $res; } - + /** - * Returns a human friendly description of the filter. - * @return string filter description + * Returns a human friendly description of the filter used as label. + * @param array $data filter settings + * @return string active filter label */ - function getDescription() { - if(is_array($this->_fields)) { - $res = $this->_fields[$this->_field] . ' '; - } else { - $res = $this->_label . ' '; - } - if($this->_value && $this->_value2) { - $res .= get_string('isbetween', 'filters', array(userdate($this->_value), userdate($this->_value2))); - } else if($this->_value) { - $res .= get_string('isafter', 'filters', userdate($this->_value)); - } else { - $res .= get_string('isbefore', 'filters', userdate($this->_value2)); + function get_label($data) { + $after = $data['after']; + $before = $data['before']; + $field = $this->_field; + + $a = new object(); + $a->label = $this->_label; + $a->after = userdate($after); + $a->before = userdate($before); + + if ($after and $before) { + return get_string('datelabelisbetween', 'filters', $a); + + } else if ($after) { + return get_string('datelabelisafter', 'filters', $a); + + } else if ($before) { + return get_string('datelabelisbefore', 'filters', $a); } - return $res; + return ''; } } ?> \ No newline at end of file diff --git a/user/filters/globalrole.php b/user/filters/globalrole.php index 20222113ee..53a03ee3b3 100644 --- a/user/filters/globalrole.php +++ b/user/filters/globalrole.php @@ -1,29 +1,29 @@ dirroot . '/user/filters/lib.php'); +require_once($CFG->dirroot.'/user/filters/lib.php'); /** * User filter based on global roles. */ class user_filter_globalrole extends user_filter_type { + /** * Constructor * @param string $name the name of the filter instance * @param string $label the label of the filter instance - * @param string $field the field used for filtering data - * @param int $value id of the role (used for filtering data); 0 = any role + * @param boolean $advanced advanced form element flag */ - function user_filter_globalrole($name, $label, $field='id', $value=0) { - parent::user_filter_type($name, $label, $field, $value); + function user_filter_globalrole($name, $label, $advanced) { + parent::user_filter_type($name, $label, $advanced); } - + /** * Returns an array of available roles * @return array of availble roles */ - function getRoles() { - $context =& get_context_instance(CONTEXT_SYSTEM); - $roles =& array_merge(array(0=> get_string('anyrole','filters')), get_assignable_roles($context)); + function get_roles() { + $context = get_context_instance(CONTEXT_SYSTEM); + $roles = array_merge(array(0=> get_string('anyrole','filters')), get_assignable_roles($context)); return $roles; } @@ -32,42 +32,57 @@ class user_filter_globalrole extends user_filter_type { * @param object $mform a MoodleForm object to setup */ function setupForm(&$mform) { - $obj =& $mform->addElement('select', $this->_name, $this->_label, $this->getRoles()); - $obj->setHelpButton(array('globalrole','','filters')); - $mform->setDefault($this->_name, $this->_value); + $obj =& $mform->addElement('select', $this->_name, $this->_label, $this->get_roles()); + $obj->setHelpButton(array('globalrole', '', 'filters')); + $mform->setDefault($this->_name, 0); + if ($this->_advanced) { + $mform->setAdvanced($this->_name); + } } - + /** * Retrieves data from the form data * @param object $formdata data submited with the form + * @return mixed array filter data or false when filter not set */ - function checkData($formdata) { + function check_data($formdata) { $field = $this->_name; - $this->_value = (string)@$formdata->$field; + + if (array_key_exists($field, $formdata) and !empty($formdata->$field)) { + return array('value' => (int)$formdata->$field); + } + return false; } /** * Returns the condition to be used with SQL where + * @param array $data filter settings * @return string the filtering condition or null if the filter is disabled */ - function getSQLFilter() { + function get_sql_filter($data) { global $CFG; - if(empty($this->_value)) { - return null; - } - $timenow = time(); - $where = 'WHERE contextlevel=10 AND roleid='. $this->_value . ' AND timestart<' . $timenow .' AND (timeend=0 OR timeend>'. $timenow . ')'; - return $this->_field . " IN (SELECT userid FROM {$CFG->prefix}role_assignments a ". - "INNER JOIN {$CFG->prefix}context b ON a.contextid=b.id ". - $where . ')'; + $value = $data['value']; + + $timenow = round(time(), 100); + + return "id IN (SELECT userid + FROM {$CFG->prefix}role_assignments a + WHERE a.contextid=".SYSCONTEXTID." AND a.roleid=$value AND a.timestart<$timenow + AND (a.timeend=0 OR a.timeend>$timenow))"; } - + /** - * Returns a human friendly description of the filter. - * @return string filter description + * Returns a human friendly description of the filter used as label. + * @param array $data filter settings + * @return string active filter label */ - function getDescription() { - $roles =& $this->getRoles(); - return $this->_label . ' is ' . $roles[$this->_value]; + function get_label($data) { + $rolename = get_field('role', 'name', 'id', $data['value']); + + $a = new object(); + $a->label = $this->_label; + $a->value = '"'.format_string($rolename).'"'; + + return get_string('globalrolelabel', 'filters', $a); } } diff --git a/user/filters/lib.php b/user/filters/lib.php index ba6e92dafe..85db4d69c3 100644 --- a/user/filters/lib.php +++ b/user/filters/lib.php @@ -1,60 +1,239 @@ dirroot.'/user/filters/text.php'); +require_once($CFG->dirroot.'/user/filters/date.php'); +require_once($CFG->dirroot.'/user/filters/select.php'); +require_once($CFG->dirroot.'/user/filters/simpleselect.php'); +require_once($CFG->dirroot.'/user/filters/courserole.php'); +require_once($CFG->dirroot.'/user/filters/globalrole.php'); +require_once($CFG->dirroot.'/user/filters/profilefield.php'); +require_once($CFG->dirroot.'/user/filters/yesno.php'); +require_once($CFG->dirroot.'/user/filters/user_filter_forms.php'); + + /** - * Library of functions and constants for user filters + * User filtering wrapper class. */ +class user_filtering { + var $_fields; + var $_addform; + var $_activeform; + + /** + * Contructor + * @param array array of visible user fields + * @param string base url used for submission/return, null if the same of current page + * @param array extra page parameters + */ + function user_filtering($fieldnames=null, $baseurl=null, $extraparams=null) { + global $SESSION; + + if (!isset($SESSION->user_filtering)) { + $SESSION->user_filtering = array(); + } + + if (empty($fieldnames)) { + $fieldnames = array('realname'=>0, 'lastname'=>1, 'firstname'=>1, 'email'=>1, 'city'=>1, 'country'=>1, + 'confirmed'=>1, 'profile'=>1, 'courserole'=>1, 'systemrole'=>1, + 'firstaccess'=>1, 'lastaccess'=>1, 'lastlogin'=>1, 'username'=>1, 'auth'=>1, 'mnethostid'=>1); + } + + $this->_fields = array(); + + foreach ($fieldnames as $fieldname=>$advanced) { + if ($field = $this->get_field($fieldname, $advanced)) { + $this->_fields[$fieldname] = $field; + } + } + + // fist the new filter form + $this->_addform = new user_add_filter_form($baseurl, array('fields'=>$this->_fields, 'extraparams'=>$extraparams)); + if ($adddata = $this->_addform->get_data(false)) { + foreach($this->_fields as $fname=>$field) { + $data = $field->check_data($adddata); + if ($data === false) { + continue; // nothing new + } + if (!array_key_exists($fname, $SESSION->user_filtering)) { + $SESSION->user_filtering[$fname] = array(); + } + $SESSION->user_filtering[$fname][] = $data; + } + // clear the form + $_POST = array(); + $this->_addform = new user_add_filter_form($baseurl, array('fields'=>$this->_fields, 'extraparams'=>$extraparams)); + } + + // now the active filters + $this->_activeform = new user_active_filter_form($baseurl, array('fields'=>$this->_fields, 'extraparams'=>$extraparams)); + if ($adddata = $this->_activeform->get_data(false)) { + if (!empty($adddata->removeall)) { + $SESSION->user_filtering = array(); -require_once($CFG->dirroot . '/user/filters/user_filter_form.php'); + } else if (!empty($adddata->removeselected) and !empty($adddata->filter)) { + foreach($adddata->filter as $fname=>$instances) { + foreach ($instances as $i=>$val) { + if (empty($val)) { + continue; + } + unset($SESSION->user_filtering[$fname][$i]); + } + } + } + // clear+reload the form + $_POST = array(); + $this->_activeform = new user_active_filter_form($baseurl, array('fields'=>$this->_fields, 'extraparams'=>$extraparams)); + } + // now the active filters + } + + /** + * Creates known user filter if present + * @param string $fieldname + * @param boolean $advanced + * @return object filter + */ + function get_field($fieldname, $advanced) { + global $USER; + + switch ($fieldname) { + case 'username': return new user_filter_text('username', get_string('username'), $advanced, 'username'); + case 'realname': return new user_filter_text('realname', get_string('fullname'), $advanced, sql_fullname()); + case 'lastname': return new user_filter_text('lastname', get_string('lastname'), $advanced, 'lastname'); + case 'firstname': return new user_filter_text('firstname', get_string('firstname'), $advanced, 'firstname'); + case 'email': return new user_filter_text('email', get_string('email'), $advanced, 'email'); + case 'city': return new user_filter_text('city', get_string('city'), $advanced, 'city'); + case 'country': return new user_filter_select('country', get_string('country'), $advanced, 'country', get_list_of_countries(), $USER->country); + case 'confirmed': return new user_filter_yesno('confirmed', get_string('confirm'), $advanced, 'confirmed'); + case 'profile': return new user_filter_profilefield('profile', get_string('profile'), $advanced); + case 'courserole': return new user_filter_courserole('courserole', get_string('courserole', 'filters'), $advanced); + case 'systemrole': return new user_filter_globalrole('systemrole', get_string('globalrole', 'role'), $advanced); + case 'firstaccess': return new user_filter_date('firstaccess', get_string('firstaccess', 'filters'), $advanced, 'firstaccess'); + case 'lastaccess': return new user_filter_date('lastaccess', get_string('lastaccess'), $advanced, 'lastaccess'); + case 'lastlogin': return new user_filter_date('lastlogin', get_string('lastlogin'), $advanced, 'lastlogin'); + case 'auth': + $plugins = get_list_of_plugins('auth'); + $choices = array(); + foreach ($plugins as $auth) { + $choices[$auth] = get_string("auth_{$auth}title", 'auth'); + } + return new user_filter_simpleselect('auth', get_string('authentication'), $advanced, 'auth', $choices); + + case 'mnethostid': + if (!$hosts = get_records('mnet_host', '', '', 'id', 'id, wwwroot, name')) { + return null; + } + $choices = array(); + foreach ($hosts as $host) { + if (empty($host->wwwroot)) { + continue; // skip all hosts + } + $choices[$host->id] = $host->name.' ('.$host->wwwroot.')'; + } + if (count($choices < 2)) { + return null; // filter not needed + } + return new user_filter_simpleselect('mnethostid', 'mnethostid', $advanced, 'mnethostid', $choices); + + default: return null; + } + } + + /** + * Returns sql where statement based on active user filters + * @param string $extra sql + * @return string + */ + function get_sql_filter($extra='') { + global $SESSION; + + $sqls = array(); + if ($extra != '') { + $sqls[] = $extra; + } + + if (!empty($SESSION->user_filtering)) { + foreach ($SESSION->user_filtering as $fname=>$datas) { + if (!array_key_exists($fname, $this->_fields)) { + continue; // filter not used + } + $field = $this->_fields[$fname]; + foreach($datas as $i=>$data) { + $sqls[] = $field->get_sql_filter($data); + } + } + } + + if (empty($sqls)) { + return ''; + } else { + return implode(' AND ', $sqls); + } + } + + /** + * Print the add filter form. + */ + function display_add() { + $this->_addform->display(); + } + + /** + * Print the active filter form. + */ + function display_active() { + $this->_activeform->display(); + } + +} /** - * The base user filter. + * The base user filter class. All abstract classes must be implemented. */ class user_filter_type { /** * The name of this filter instance. */ var $_name; + /** * The label of this filter instance. */ var $_label; + /** - * The field database used for filtering data. + * Advanced form element flag */ - var $_field; - /** - * The value used for filtering data. - */ - var $_value; + var $_advanced; + /** * Constructor * @param string $name the name of the filter instance * @param string $label the label of the filter instance - * @param string $field the field used for filtering data - * @param string $value the value used for filtering data + * @param boolean $advanced advanced form element flag */ - function user_filter_type($name, $label, $field, $value=null) { - $this->_name = $name; - $this->_label = $label; - $this->_field = $field; - $this->_value = $value; + function user_filter_type($name, $label, $advanced) { + $this->_name = $name; + $this->_label = $label; + $this->_advanced = $advanced; } - + /** * Returns the condition to be used with SQL where + * @param array $data filter settings * @return string the filtering condition or null if the filter is disabled */ - function getSQLFilter() { - return $this->_field . '="' . $this->_value . '"'; + function get_sql_filter($data) { + error('Abstract method get_sql_filter() called - must be implemented'); } - + /** * Retrieves data from the form data * @param object $formdata data submited with the form + * @return mixed array filter data or false when filter not set */ - function checkData($formdata) { - $field = $this->_name; - $this->_value = (string)@$formdata->$field; + function check_data($formdata) { + error('Abstract method check_data() called - must be implemented'); } /** @@ -62,15 +241,15 @@ class user_filter_type { * @param object $mform a MoodleForm object to setup */ function setupForm(&$mform) { - $mform->addElement('text', $this->_name, $this->_label); - $mform->setDefault($this->_name, $this->_value); + error('Abstract method setupForm() called - must be implemented'); } - + /** - * Returns a human friendly description of the filter. - * @return string filter description + * Returns a human friendly description of the filter used as label. + * @param array $data filter settings + * @return string active filter label */ - function getDescription() { - return $this->_label . ' is "' . $this->_value . '"'; + function get_label($data) { + error('Abstract method get_label() called - must be implemented'); } } diff --git a/user/filters/profilefield.php b/user/filters/profilefield.php index 40ed2ae649..8a1e89824a 100644 --- a/user/filters/profilefield.php +++ b/user/filters/profilefield.php @@ -1,61 +1,46 @@ dirroot . '/user/filters/lib.php'); +require_once($CFG->dirroot.'/user/filters/lib.php'); /** * User filter based on values of custom profile fields. */ class user_filter_profilefield extends user_filter_type { - /** - * operator used for comparison of data - */ - var $_operator; - /** - * profile field to look at (0 - all fields) - */ - var $_profile_field; + /** * Constructor * @param string $name the name of the filter instance * @param string $label the label of the filter instance - * @param string $field the field used for filtering data - * @param string $value the value of the profile field (used for filtering data) - * @param int $profile_field id of the profile field to look in - * @param int $operator code of the comparison operator + * @param boolean $advanced advanced form element flag */ - function user_filter_profilefield($name, $label, $field='id', $value=null, $profile_field=0, $operator=0) { - parent::user_filter_type($name, $label, $field, $value); - $this->_operator = $operator; - $this->_profile_field = $profile_field; + function user_filter_profilefield($name, $label, $advanced) { + parent::user_filter_type($name, $label, $advanced); } - + /** * Returns an array of comparison operators * @return array of comparison operators */ - function getOperators() { - return array( - get_string('contains', 'filters'), - get_string('doesnotcontain','filters'), - get_string('isequalto','filters'), - get_string('startswith','filters'), - get_string('endswith','filters'), - get_string('isempty','filters'), - get_string('isnotdefined','filters'), - get_string('isdefined','filters'), - ); + function get_operators() { + return array(0 => get_string('contains', 'filters'), + 1 => get_string('doesnotcontain','filters'), + 2 => get_string('isequalto','filters'), + 3 => get_string('startswith','filters'), + 4 => get_string('endswith','filters'), + 5 => get_string('isempty','filters'), + 6 => get_string('isnotdefined','filters'), + 7 => get_string('isdefined','filters')); } - + /** * Returns an array of custom profile fields * @return array of profile fields */ - function getProfileFields() { - $fields =& get_records_select('user_info_field', '', 'shortname', 'id,shortname'); - if(empty($fields)) { + function get_profile_fields() { + if (!$fields = get_records_select('user_info_field', '', 'shortname', 'id,shortname')) { return null; } - $res[0] = get_string('anyfield','filters'); + $res = array(0 => get_string('anyfield', 'filters')); foreach($fields as $k=>$v) { $res[$k] = $v->shortname; } @@ -67,116 +52,123 @@ class user_filter_profilefield extends user_filter_type { * @param object $mform a MoodleForm object to setup */ function setupForm(&$mform) { - $profile_fields =& $this->getProfileFields(); - if(empty($profile_fields)) { + $profile_fields = $this->get_profile_fields(); + if (empty($profile_fields)) { return; } $objs = array(); - $objs[] =& $mform->createElement('select', $this->_name . '_fld', null, $profile_fields); - $objs[] =& $mform->createElement('select', $this->_name . '_op', null, $this->getOperators()); + $objs[] =& $mform->createElement('select', $this->_name.'_fld', null, $profile_fields); + $objs[] =& $mform->createElement('select', $this->_name.'_op', null, $this->get_operators()); $objs[] =& $mform->createElement('text', $this->_name, null); - $grp =& $mform->addElement('group', $this->_name . '_grp', $this->_label, $objs, '', false); + $grp =& $mform->addElement('group', $this->_name.'_grp', $this->_label, $objs, '', false); $grp->setHelpButton(array('profilefield','','filters')); - $mform->setDefault($this->_name . '_fld', $this->_profile_field); - $mform->setDefault($this->_name . '_op', $this->_operator); - $mform->setDefault($this->_name, $this->_value); + if ($this->_advanced) { + $mform->setAdvanced($this->_name.'_grp'); + } } - + /** * Retrieves data from the form data * @param object $formdata data submited with the form + * @return mixed array filter data or false when filter not set */ - function checkData($formdata) { - $field = $this->_name; - $operator = $field . '_op'; - $profile_field = $field . '_fld'; - $this->_value = (string)@$formdata->$field; - $this->_operator = (int)@$formdata->$operator; - $this->_profile_field = (int)@$formdata->$profile_field; + function check_data($formdata) { + $field = $this->_name; + $operator = $field.'_op'; + $profile = $field.'_fld'; + + if (array_key_exists($profile, $formdata)) { + if ($formdata->$operator < 5 and $formdata->$field === '') { + return false; + } + + return array('value' => (string)$formdata->$field, + 'operator' => (int)$formdata->$operator, + 'profile' => (int)$formdata->$profile); + } } /** * Returns the condition to be used with SQL where + * @param array $data filter settings * @return string the filtering condition or null if the filter is disabled */ - function getSQLFilter() { + function get_sql_filter($data) { global $CFG; - $where = ''; - $op = ' IN '; - switch($this->_operator) { - case 0: // contains - if(empty($this->_value)) { - return null; - } - $where = 'data ' . sql_ilike(). ' "%' . $this->_value . '%"'; - break; - case 1: // does not contain - if(empty($this->_value)) { - return null; - } - $where = 'data NOT ' . sql_ilike(). ' "%' . $this->_value . '%"'; - break; - case 2: // equal to - if(empty($this->_value)) { - return null; - } - $where = 'data="' . $this->_value . '"'; - break; - case 3: // starts with - if(empty($this->_value)) { - return null; - } - $where = 'data ' . sql_ilike(). ' "' . $this->_value . '%"'; - break; - case 4: // ends with - if(empty($this->_value)) { - return null; - } - $where = 'data ' . sql_ilike(). ' "%' . $this->_value . '"'; - break; - case 5: // empty - $where = 'data=""'; - break; - case 6: // is not defined - $op = ' NOT IN '; - break; - case 7: // is defined - break; + + $profile = $data['profile']; + $operator = $data['operator']; + $value = addslashes($data['value']); + + $where = ""; + $op = " IN "; + $ilike = sql_ilike(); + + if ($operator < 5 and $value === '') { + return ''; } - if(!empty($this->_profile_field)) { - if(!empty($where)) { - $where = ' AND ' . $where; + + switch($operator) { + case 0: // contains + $where = "data $ilike '%$value%'"; break; + case 1: // does not contain + $where = "data NOT $ilike '%$value%'"; break; + case 2: // equal to + $where = "data $ilike '$value'"; break; + case 3: // starts with + $where = "data $ilike '$value%'"; break; + case 4: // ends with + $where = "data $ilike '%$value'"; break; + case 5: // empty + $where = "data=''"; break; + case 6: // is not defined + $op = " NOT IN "; break; + case 7: // is defined + break; + } + if ($profile) { + if ($where !== '') { + $where = " AND $where"; } - $where = 'fieldid=' . $this->_profile_field . $where; + $where = "fieldid=$profile $where"; } - if(!empty($where)) { - $where = ' WHERE ' . $where; + if ($where !== '') { + $where = "WHERE $where"; } - return $this->_field . $op . "(SELECT userid FROM {$CFG->prefix}user_info_data" . $where . ')'; + return "id $op (SELECT userid FROM {$CFG->prefix}user_info_data $where)"; } - + /** - * Returns a human friendly description of the filter. - * @return string filter description + * Returns a human friendly description of the filter used as label. + * @param array $data filter settings + * @return string active filter label */ - function getDescription() { - $res = ''; - $operators =& $this->getOperators(); - $profilefields =& $this->getProfileFields(); - switch($this->_operator) { - case 0: // contains - case 1: // doesn't contain - case 2: // equal to - case 3: // starts with - case 4: // ends with - $res = $this->_label . ': '. $profilefields[$this->_profile_field] . ' ' . $operators[$this->_operator]. ' "' . stripslashes($this->_value) . '"'; - break; - case 5: // empty - case 6: // is not defined - case 7: // is defined - $res = $this->_label . ': '. $profilefields[$this->_profile_field] . ' ' . $operators[$this->_operator]; - break; + function get_label($data) { + $operators = $this->get_operators(); + $profilefields = $this->get_profile_fields(); + + $profile = $data['profile']; + $operator = $data['operator']; + $value = $data['value']; + + $a = new object(); + $a->label = $this->_label; + $a->value = $value; + $a->profile = $profilefields[$profile]; + $a->operator = $operators[$operator]; + + switch($operator) { + case 0: // contains + case 1: // doesn't contain + case 2: // equal to + case 3: // starts with + case 4: // ends with + return get_string('profilelabel', 'filters', $a); + case 5: // empty + case 6: // is not defined + case 7: // is defined + return get_string('profilelabelnovalue', 'filters', $a); } - return $res; + return ''; } } diff --git a/user/filters/radios.php b/user/filters/radios.php deleted file mode 100644 index ae7162a9f7..0000000000 --- a/user/filters/radios.php +++ /dev/null @@ -1,80 +0,0 @@ -dirroot . '/user/filters/lib.php'); - -/** - * Generic filter with radio buttons for integer fields. - */ -class user_filter_radios extends user_filter_type { - /** - * options for the radio buttons - */ - var $_options; - /** - * id of the option which disables the filter - */ - var $_offoption; - /** - * Constructor - * @param string $name the name of the filter instance - * @param string $label the label of the filter instance - * @param string $field the field used for filtering data - * @param array $options associative array used to generate the radio buttons - * @param boolean $offoption true if a "don't care" option should be generated - * @param int $value the value used for filtering data - */ - function user_filter_radios($name, $label, $field, $options, $offoption=true, $value=null) { - parent::user_filter_type($name, $label, $field, $value); - $this->_options = $options; - if($offoption) { - $this->_offoption = @min(array_keys($options)) - 1; - } else { - $this->_offoption = null; - } - } - - /** - * Adds controls specific to this filter in the form. - * @param object $mform a MoodleForm object to setup - */ - function setupForm(&$mform) { - $objs = array(); - if(!is_null($this->_offoption)) { - $objs[] =& $mform->createElement('radio', $this->_name, null, get_string('anyvalue', 'filters'), $this->_offoption); - } - foreach($this->_options as $k=>$v) { - $objs[] =& $mform->createElement('radio', $this->_name, null, $v, $k); - } - $grp =& $mform->addElement('group', $this->_name . '_grp', $this->_label, $objs, '', false); - $mform->setDefault($this->_name, $this->_value); - $grp->setHelpButton(array('radios','','filters')); - } - - /** - * Retrieves data from the form data - * @param object $formdata data submited with the form - */ - function checkData($formdata) { - $field = $this->_name; - $this->_value = (int)@$formdata->$field; - } - - /** - * Returns the condition to be used with SQL where - * @return string the filtering condition or null if the filter is disabled - */ - function getSQLFilter() { - if($this->_value === $this->_offoption) { - return null; - } - return $this->_field . '=' . $this->_value; - } - - /** - * Returns a human friendly description of the filter. - * @return string filter description - */ - function getDescription() { - return $this->_label . ' is ' . $this->_options[$this->_value]; - } -} diff --git a/user/filters/select.php b/user/filters/select.php index 4b1777b651..7498c55cff 100644 --- a/user/filters/select.php +++ b/user/filters/select.php @@ -1,43 +1,44 @@ dirroot . '/user/filters/lib.php'); +require_once($CFG->dirroot.'/user/filters/lib.php'); /** * Generic filter based on a list of values. */ class user_filter_select extends user_filter_type { - /** - * operator used for comparison of data - */ - var $_operator; /** * options for the list values */ var $_options; + + var $_field; + + var $_default; + /** * Constructor * @param string $name the name of the filter instance * @param string $label the label of the filter instance - * @param string $field the field used for filtering data - * @param string $value the value used for filtering data - * @param int $operator code of the comparison operator + * @param boolean $advanced advanced form element flag + * @param string $field user table filed name + * @param array $options select options + * @param mixed $default option */ - function user_filter_select($name, $label, $field, $options, $value=null, $operator=null) { - parent::user_filter_type($name, $label, $field, $value); - $this->_operator = $operator; + function user_filter_select($name, $label, $advanced, $field, $options, $default=null) { + parent::user_filter_type($name, $label, $advanced); + $this->_field = $field; $this->_options = $options; + $this->_default = $default; } - + /** * Returns an array of comparison operators * @return array of comparison operators */ - function getOperators() { - return array( - get_string('isanyvalue','filters'), - get_string('isequalto','filters'), - get_string('isnotequalto','filters'), - ); + function get_operators() { + return array(0 => get_string('isanyvalue','filters'), + 1 => get_string('isequalto','filters'), + 2 => get_string('isnotequalto','filters')); } /** @@ -46,56 +47,77 @@ class user_filter_select extends user_filter_type { */ function setupForm(&$mform) { $objs = array(); - $objs[] =& $mform->createElement('select', $this->_name . '_op', null, $this->getOperators()); + $objs[] =& $mform->createElement('select', $this->_name.'_op', null, $this->get_operators()); $objs[] =& $mform->createElement('select', $this->_name, null, $this->_options); - $grp =& $mform->addElement('group', $this->_name . '_grp', $this->_label, $objs, '', false); - $grp->setHelpButton(array('select','','filters')); - $mform->setDefault($this->_name . '_op', $this->_operator); - $mform->setDefault($this->_name, $this->_value); + $grp =& $mform->addElement('group', $this->_name.'_grp', $this->_label, $objs, '', false); + $grp->setHelpButton(array('select', '', 'filters')); + $mform->disabledIf($this->_name, $this->_name.'_op', 'eq', 0); + if (!is_null($this->_default)) { + $mform->setDefault($this->_name, $this->_default); + } + if ($this->_advanced) { + $mform->setAdvanced($this->_name.'_grp'); + } } - + /** * Retrieves data from the form data * @param object $formdata data submited with the form + * @return mixed array filter data or false when filter not set */ - function checkData($formdata) { - $field = $this->_name; - $operator = $field . '_op'; - $this->_value = (string)@$formdata->$field; - $this->_operator = (int)@$formdata->$operator; + function check_data($formdata) { + $field = $this->_name; + $operator = $field.'_op'; + + if (array_key_exists($field, $formdata) and !empty($formdata->$operator)) { + return array('operator' => (int)$formdata->$operator, + 'value' => (string)$formdata->$field); + } + + return false; } /** * Returns the condition to be used with SQL where + * @param array $data filter settings * @return string the filtering condition or null if the filter is disabled */ - function getSQLFilter() { - switch($this->_operator) { - default: - return null; - case 1: // equal to - $res = '="' . $this->_value . '"'; - break; - case 2: // not equal to - $res = '<>"' . $this->_value . '"'; - break; + function get_sql_filter($data) { + $operator = $data['operator']; + $value = addslashes($data['value']); + $field = $this->_field; + + switch($operator) { + case 1: // equal to + $res = "='$value'"; break; + case 2: // not equal to + $res = "<>'$value'"; break; + default: + return ''; } - return $this->_field . $res; + return $field.$res; } - + /** - * Returns a human friendly description of the filter. - * @return string filter description + * Returns a human friendly description of the filter used as label. + * @param array $data filter settings + * @return string active filter label */ - function getDescription() { - $operators = $this->getOperators(); - switch($this->_operator) { - case 1: // equal to - case 2: // not equal to - $res = $this->_label . ' ' . $operators[$this->_operator]. ' "' . $this->_options[stripslashes($this->_value)] . '"'; - break; + function get_label($data) { + $operators = $this->get_operators(); + $operator = $data['operator']; + $value = $data['value']; + + if (empty($operator)) { + return ''; } - return $res; + + $a = new object(); + $a->label = $this->_label; + $a->value = '"'.s($this->_options[$value]).'"'; + $a->operator = $operators[$operator]; + + return get_string('selectlabel', 'filters', $a); } } diff --git a/user/filters/simpleselect.php b/user/filters/simpleselect.php new file mode 100644 index 0000000000..81062cea4d --- /dev/null +++ b/user/filters/simpleselect.php @@ -0,0 +1,88 @@ +dirroot.'/user/filters/lib.php'); + +/** + * Generic filter based on a list of values. + */ +class user_filter_simpleselect extends user_filter_type { + /** + * options for the list values + */ + var $_options; + + var $_field; + + /** + * Constructor + * @param string $name the name of the filter instance + * @param string $label the label of the filter instance + * @param boolean $advanced advanced form element flag + * @param string $field user table filed name + * @param array $options select options + */ + function user_filter_simpleselect($name, $label, $advanced, $field, $options) { + parent::user_filter_type($name, $label, $advanced); + $this->_field = $field; + $this->_options = $options; + } + + /** + * Adds controls specific to this filter in the form. + * @param object $mform a MoodleForm object to setup + */ + function setupForm(&$mform) { + $choices = array(''=>get_string('anyvalue', 'filters')) + $this->_options; + $mform->addElement('select', $this->_name, $this->_label, $choices); + $mform->setHelpButton($this->_name, array('simpleselect', '', 'filters')); + if ($this->_advanced) { + $mform->setAdvanced($this->_name); + } + } + + /** + * Retrieves data from the form data + * @param object $formdata data submited with the form + * @return mixed array filter data or false when filter not set + */ + function check_data($formdata) { + $field = $this->_name; + + if (array_key_exists($field, $formdata) and $formdata->$field !== '') { + return array('value'=>(string)$formdata->$field); + } + + return false; + } + + /** + * Returns the condition to be used with SQL where + * @param array $data filter settings + * @return string the filtering condition or null if the filter is disabled + */ + function get_sql_filter($data) { + $value = addslashes($data['value']); + $field = $this->_field; + if ($value == '') { + return ''; + } + return "$field='$value'"; + } + + /** + * Returns a human friendly description of the filter used as label. + * @param array $data filter settings + * @return string active filter label + */ + function get_label($data) { + $value = $data['value']; + + $a = new object(); + $a->label = $this->_label; + $a->value = '"'.s($this->_options[$value]).'"'; + $a->operator = get_string('isequalto','filters'); + + return get_string('selectlabel', 'filters', $a); + } +} + diff --git a/user/filters/text.php b/user/filters/text.php index fbcfa65934..b92624be03 100644 --- a/user/filters/text.php +++ b/user/filters/text.php @@ -1,41 +1,36 @@ dirroot . '/user/filters/lib.php'); +require_once($CFG->dirroot.'/user/filters/lib.php'); /** * Generic filter for text fields. */ class user_filter_text extends user_filter_type { - /** - * operator used for comparison of data - */ - var $_operator; + var $_field; + /** * Constructor * @param string $name the name of the filter instance * @param string $label the label of the filter instance - * @param string $field the field used for filtering data - * @param string $value the value used for filtering data - * @param int $operator code of the comparison operator + * @param boolean $advanced advanced form element flag + * @param string $field user table filed name */ - function user_filter_text($name, $label, $field, $value=null, $operator=0) { - parent::user_filter_type($name, $label, $field, $value); - $this->_operator = $operator; + function user_filter_text($name, $label, $advanced, $field) { + parent::user_filter_type($name, $label, $advanced); + $this->_field = $field; } - + /** * Returns an array of comparison operators * @return array of comparison operators */ function getOperators() { - return array( - get_string('contains', 'filters'), - get_string('doesnotcontain','filters'), - get_string('isequalto','filters'), - get_string('startswith','filters'), - get_string('endswith','filters'), - get_string('isempty','filters'), - ); + return array(0 => get_string('contains', 'filters'), + 1 => get_string('doesnotcontain','filters'), + 2 => get_string('isequalto','filters'), + 3 => get_string('startswith','filters'), + 4 => get_string('endswith','filters'), + 5 => get_string('isempty','filters')); } /** @@ -44,91 +39,98 @@ class user_filter_text extends user_filter_type { */ function setupForm(&$mform) { $objs = array(); - $objs[] =& $mform->createElement('select', $this->_name . '_op', null, $this->getOperators()); + $objs[] =& $mform->createElement('select', $this->_name.'_op', null, $this->getOperators()); $objs[] =& $mform->createElement('text', $this->_name, null); - $grp =& $mform->addElement('group', $this->_name . '_grp', $this->_label, $objs, '', false); + $grp =& $mform->addElement('group', $this->_name.'_grp', $this->_label, $objs, '', false); $grp->setHelpButton(array('text','','filters')); - $mform->setDefault($this->_name, $this->_value); - $mform->setDefault($this->_name . '_op', $this->_operator); + $mform->disabledIf($this->_name, $this->_name.'_op', 'eq', 5); + if ($this->_advanced) { + $mform->setAdvanced($this->_name.'_grp'); + } } - + /** * Retrieves data from the form data * @param object $formdata data submited with the form + * @return mixed array filter data or false when filter not set */ - function checkData($formdata) { - $field = $this->_name; - $operator = $field . '_op'; - $this->_value = (string)@$formdata->$field; - $this->_operator = (int)@$formdata->$operator; + function check_data($formdata) { + $field = $this->_name; + $operator = $field.'_op'; + + if (array_key_exists($operator, $formdata)) { + if ($formdata->$operator != 5 and $formdata->$field == '') { + // no data - no change except for empty filter + return false; + } + return array('operator'=>(int)$formdata->$operator, 'value'=>$formdata->$field); + } + + return false; } /** * Returns the condition to be used with SQL where + * @param array $data filter settings * @return string the filtering condition or null if the filter is disabled */ - function getSQLFilter() { - switch($this->_operator) { - default: - return null; - case 0: // contains - if(empty($this->_value)) { - return null; - } - $res = ' ' . sql_ilike(). ' "%' . $this->_value . '%"'; - break; - case 1: // does not contain - if(empty($this->_value)) { - return null; - } - $res = ' NOT ' . sql_ilike(). ' "%' . $this->_value . '%"'; - break; - case 2: // equal to - if(empty($this->_value)) { - return null; - } - $res = '="' . $this->_value . '"'; - break; - case 3: // starts with - if(empty($this->_value)) { - return null; - } - $res = ' ' . sql_ilike(). ' "' . $this->_value . '%"'; - break; - case 4: // ends with - if(empty($this->_value)) { - return null; - } - $res = ' ' . sql_ilike(). ' "%' . $this->_value . '"'; - break; - case 5: // empty - if(empty($this->_value)) { - return null; - } - $res = '=""'; - break; + function get_sql_filter($data) { + $operator = $data['operator']; + $value = addslashes($data['value']); + $field = $this->_field; + + if ($operator != 5 and $value === '') { + return ''; + } + + $ilike = sql_ilike(); + + switch($operator) { + case 0: // contains + $res = "$ilike '%$value%'"; break; + case 1: // does not contain + $res = "NOT $ilike '%$value%'"; break; + case 2: // equal to + $res = "$ilike '$value'"; break; + case 3: // starts with + $res = "$ilike '$value%'"; break; + case 4: // ends with + $res = "$ilike '%$value'"; break; + case 5: // empty + $res = "=''"; break; + default: + return ''; } - return $this->_field . $res; + return $field.' '.$res; } - + /** - * Returns a human friendly description of the filter. - * @return string filter description + * Returns a human friendly description of the filter used as label. + * @param array $data filter settings + * @return string active filter label */ - function getDescription() { + function get_label($data) { + $operator = $data['operator']; + $value = $data['value']; $operators = $this->getOperators(); - switch($this->_operator) { - case 0: // contains - case 1: // doesn't contain - case 2: // equal to - case 3: // starts with - case 4: // ends with - $res = $operators[$this->_operator]. ' "' . stripslashes($this->_value) . '"'; - break; - case 5: // empty - $res = $operators[$this->_operator]; - break; + + $a = new object(); + $a->label = $this->_label; + $a->value = '"'.s($value).'"'; + $a->operator = $operators[$operator]; + + + switch ($operator) { + case 0: // contains + case 1: // doesn't contain + case 2: // equal to + case 3: // starts with + case 4: // ends with + return get_string('textlabel', 'filters', $a); + case 5: // empty + return get_string('textlabelnovalue', 'filters', $a); } - return $this->_label . ' ' . $res; + + return ''; } } diff --git a/user/filters/user_filter_form.php b/user/filters/user_filter_form.php deleted file mode 100644 index 65534ef1c7..0000000000 --- a/user/filters/user_filter_form.php +++ /dev/null @@ -1,178 +0,0 @@ -libdir.'/formslib.php'); -//require_once($CFG->libdir . '/form/submit.php'); // (abautu) is it necesary? i don't think so - -class user_filter_form extends moodleform { - /** - * array of filter type objects - */ - var $_filtersTypes = array(); - - // form definition - function definition() { - global $SESSION; - // add controls for each filter type in the new filter group - $mform =& $this->_form; - $this->_filtersTypes =& $this->_customdata; - $mform->addElement('header', 'newfilter', get_string('newfilter','filters')); - foreach($this->_filtersTypes as $ft) { - $ft->setupForm($mform); - } - $objs = array(); - $objs[] = &$mform->createElement('submit', 'add ', get_string('addfilter','filters')); - $objs[] = &$mform->createElement('submit', 'set', get_string('setfilter','filters')); - $mform->addElement('group', 'addfilterbar', '', $objs, ' ', false); - - // add controls for each active filter in the active filters group - $mform->addElement('header', 'actfilterhdr', get_string('actfilterhdr','filters')); - $objs = array(); - $objs[] = &$mform->createElement('cancel', 'remove', get_string('removeselected','filters')); - $objs[] = &$mform->createElement('cancel', 'cancel', get_string('removeall','filters')); - $mform->addElement('group', 'actfiltergrp', '', $objs, ' ', false); - // insert the controls before the buttons - if(!empty($SESSION->user_filter_descriptions)) { - foreach($SESSION->user_filter_descriptions as $k => $f) { - $obj = &$mform->createElement('checkbox', 'filter['.$k.']', null, $f); - $mform->insertElementBefore($obj, 'actfiltergrp'); - } - } - } - - /** - * Removes an active filter from the form and filters list. - * @param int $key id of filter to remove - */ - function _removeFilter($key) { - global $SESSION; - unset($SESSION->user_filter_clauses[$key]); - unset($SESSION->user_filter_descriptions[$key]); - $this->_form->removeElement('filter['.$key.']'); - } - - /** - * Removes all active filters from the form and filters list. - */ - function _removeFilters() { - global $SESSION; - if(!empty($SESSION->user_filter_clauses)) { - foreach($SESSION->user_filter_clauses as $key=>$f) { - $this->_removeFilter($key); - } - } - } - - /** - * Stores an active filter to the form and filters list. - * @param int $key id of filter to remove - * @param string $description human friendly description of the filter - * @param string $clauses SQL where condition - */ - function _insertFilter($key, $description, $clause) { - global $SESSION; - $SESSION->user_filter_clauses[$key] = $clause; - $SESSION->user_filter_descriptions[$key] = $description; - $mform =& $this->_form; - $obj = &$mform->createElement('checkbox', 'filter['.$key.']', null, $description); - $mform->insertElementBefore($obj, 'actfiltergrp'); - } - - /** - * Updates form and filters list based on data received - * @param object $data object with data received by the form - */ - function _updateFilters($data) { - global $SESSION; - // if the forms was not submited, then quit - if(is_null($data)){ - return; - } - // if cancel was pressed, then remove all filters - if(!empty($data->cancel)) { - $this->_removeFilters(); - return; - } - - // if remove was pressed, then remove selected filters - if(!empty($data->remove)) { - if(!empty($data->filter)) { - foreach($data->filter as $k=>$f) { - $this->_removeFilter($k); - } - } - return; - } - - // if set was pressed, then remove all filters before adding new ones - if(!empty($data->set)) { - $this->_removeFilters(); - } - - // in any other case, add the selected filter - // first build the filter out of each active filter type - $clauses = array(); - $descriptions = array(); - foreach($this->_filtersTypes as $ft) { - $ft->checkData($data); - $sqlFilter = $ft->getSQLFilter(); - // ignore disabled filters - if(!empty($sqlFilter)) { - $clauses[] = $sqlFilter; - $descriptions[] = $ft->getDescription(); - } - } - // if no filters are active, then quit - if(empty($clauses)) { - return; - } - - // join the filter parts and their descriptions together - $clauses = implode(' AND ', $clauses); - $descriptions = implode(', ', $descriptions); - - // check if this filter is a duplicate; if so, then quit - $lastkey = -1; - if(!empty($SESSION->user_filter_descriptions)) { - foreach($SESSION->user_filter_descriptions as $k=>$c) { - if($c == $descriptions) { - return; - } - $lastkey = $k; - } - } - // append the new filter - $this->_insertFilter($lastkey + 1, $descriptions, $clauses); - } - - function definition_after_data() { - global $SESSION; - $mform =& $this->_form; - // update the filters - $this->_updateFilters($this->get_data()); - // remove the active filters section if no filters are defined - if(empty($SESSION->user_filter_descriptions)) { - $mform->removeElement('actfiltergrp'); - $mform->removeElement('actfilterhdr'); - } - } - - /** - * Returns the complete SQL where condition coresponding to the active filters and the extra conditions - * @param mixed $extra array of SQL where conditions to be conected by ANDs or a string SQL where condition, which will be connected to the active filters conditions by AND - * @return string SQL where condition - */ - function getSQLFilter($extra='') { - global $SESSION; - if(is_array($extra)) { - $extra = implode(' AND ', $extra); - } - // join sql filters with ORs and put inside paranteses - if(!empty($SESSION->user_filter_clauses)) { - if(!empty($extra)) { - $extra .= ' AND '; - } - $extra .= '((' . implode(') OR (',$SESSION->user_filter_clauses) . '))'; - } - return $extra; - } -} diff --git a/user/filters/user_filter_forms.php b/user/filters/user_filter_forms.php new file mode 100644 index 0000000000..d1bbccdc17 --- /dev/null +++ b/user/filters/user_filter_forms.php @@ -0,0 +1,69 @@ +libdir.'/formslib.php'); + +class user_add_filter_form extends moodleform { + + function definition() { + $mform =& $this->_form; + $fields = $this->_customdata['fields']; + $extraparams = $this->_customdata['extraparams']; + + $mform->addElement('header', 'newfilter', get_string('newfilter','filters')); + + foreach($fields as $ft) { + $ft->setupForm($mform); + } + + // in case we wasnt to track some page params + if ($extraparams) { + foreach ($extraparams as $key=>$value) { + $mform->addElement('hidden', $key, $value); + } + } + + // Add button + $mform->addElement('submit', 'addfilter', get_string('addfilter','filters')); + + // Don't use last advanced state + $mform->setShowAdvanced(false); + } +} + +class user_active_filter_form extends moodleform { + + function definition() { + global $SESSION; // this is very hacky :-( + + $mform =& $this->_form; + $fields = $this->_customdata['fields']; + $extraparams = $this->_customdata['extraparams']; + + if (!empty($SESSION->user_filtering)) { + // add controls for each active filter in the active filters group + $mform->addElement('header', 'actfilterhdr', get_string('actfilterhdr','filters')); + + foreach ($SESSION->user_filtering as $fname=>$datas) { + if (!array_key_exists($fname, $fields)) { + continue; // filter not used + } + $field = $fields[$fname]; + foreach($datas as $i=>$data) { + $description = $field->get_label($data); + $mform->addElement('checkbox', 'filter['.$fname.']['.$i.']', null, $description); + } + } + + if ($extraparams) { + foreach ($extraparams as $key=>$value) { + $mform->addElement('hidden', $key, $value); + } + } + + $objs = array(); + $objs[] = &$mform->createElement('submit', 'removeselected', get_string('removeselected','filters')); + $objs[] = &$mform->createElement('submit', 'removeall', get_string('removeall','filters')); + $mform->addElement('group', 'actfiltergrp', '', $objs, ' ', false); + } + } +} diff --git a/user/filters/yesno.php b/user/filters/yesno.php index 0b5b4545e1..95aeebe218 100644 --- a/user/filters/yesno.php +++ b/user/filters/yesno.php @@ -1,19 +1,18 @@ dirroot . '/user/filters/radios.php'); - /** * Generic yes/no filter with radio buttons for integer fields. */ -class user_filter_yesno extends user_filter_radios { +class user_filter_yesno extends user_filter_simpleselect { + /** * Constructor * @param string $name the name of the filter instance * @param string $label the label of the filter instance - * @param string $field the field used for filtering data - * @param int $value the value used for filtering data + * @param boolean $advanced advanced form element flag + * @param string $field user table filed name */ - function user_filter_yesno($name, $label, $field, $value=-1) { - parent::user_filter_radios($name, $label, $field, array(0=>get_string('no'), 1=>get_string('yes')), true, $value); + function user_filter_yesno($name, $label, $advanced, $field) { + parent::user_filter_simpleselect($name, $label, $advanced, $field, array(0=>get_string('no'), 1=>get_string('yes'))); } } -- 2.39.5