diff --git a/admin/roles/lib.php b/admin/roles/lib.php index 7fc5782eb2d..b09ed4f688a 100644 --- a/admin/roles/lib.php +++ b/admin/roles/lib.php @@ -996,13 +996,14 @@ abstract class role_assign_user_selector_base extends user_selector_base { */ public function __construct($name, $options) { global $CFG; - parent::__construct($name, $options); - $this->roleid = $options['roleid']; if (isset($options['context'])) { $this->context = $options['context']; } else { $this->context = get_context_instance_by_id($options['contextid']); } + $options['accesscontext'] = $this->context; + parent::__construct($name, $options); + $this->roleid = $options['roleid']; require_once($CFG->dirroot . '/group/lib.php'); } diff --git a/admin/settings/users.php b/admin/settings/users.php index cf782b2980c..02d49b00abd 100644 --- a/admin/settings/users.php +++ b/admin/settings/users.php @@ -123,9 +123,24 @@ if ($hassiteconfig 'mycourses' => get_string('mycourses'), 'groups' => get_string('groups')))); - $temp->add(new admin_setting_configmulticheckbox('extrauserselectorfields', - get_string('extrauserselectorfields', 'admin'), get_string('configextrauserselectorfields', 'admin'), array('email' => '1'), - array('email' => get_string('email'), 'idnumber' => get_string('idnumber'), 'username' => get_string('username'), ))); + // Select fields to display as part of user identity (only to those + // with moodle/site:viewuseridentity). + // Options include fields from the user table that might be helpful to + // distinguish when adding or listing users ('I want to add the John + // Smith from Science faculty'). + // Username is not included as an option because in some sites, it might + // be a security problem to reveal usernames even to trusted staff. + // Custom user profile fields are not currently supported. + $temp->add(new admin_setting_configmulticheckbox('showuseridentity', + get_string('showuseridentity', 'admin'), + get_string('showuseridentity_desc', 'admin'), array('email' => 1), array( + 'idnumber' => get_string('idnumber'), + 'email' => get_string('email'), + 'phone1' => get_string('phone'), + 'phone2' => get_string('phone2'), + 'department' => get_string('department'), + 'institution' => get_string('institution'), + ))); $temp->add(new admin_setting_configcheckbox('enablegravatar', get_string('enablegravatar', 'admin'), get_string('enablegravatar_help', 'admin'), 0)); } diff --git a/admin/user.php b/admin/user.php index 2827ccfb07d..9453dbf7850 100644 --- a/admin/user.php +++ b/admin/user.php @@ -7,7 +7,7 @@ $delete = optional_param('delete', 0, PARAM_INT); $confirm = optional_param('confirm', '', PARAM_ALPHANUM); //md5 confirmation hash $confirmuser = optional_param('confirmuser', 0, PARAM_INT); - $sort = optional_param('sort', 'name', PARAM_ALPHA); + $sort = optional_param('sort', 'name', PARAM_ALPHANUM); $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 @@ -117,11 +117,13 @@ echo $OUTPUT->header(); // Carry on with the user listing - - $columns = array("firstname", "lastname", "email", "city", "country", "lastaccess"); + $context = context_system::instance(); + $extracolumns = get_extra_user_fields($context); + $columns = array_merge(array('firstname', 'lastname'), $extracolumns, + array('city', 'country', 'lastaccess')); foreach ($columns as $column) { - $string[$column] = get_string("$column"); + $string[$column] = get_user_field_name($column); if ($sort != $column) { $columnicon = ""; if ($column == "lastaccess") { @@ -147,7 +149,8 @@ } list($extrasql, $params) = $ufiltering->get_sql_filter(); - $users = get_users_listing($sort, $dir, $page*$perpage, $perpage, '', '', '', $extrasql, $params); + $users = get_users_listing($sort, $dir, $page*$perpage, $perpage, '', '', '', + $extrasql, $params, $context); $usercount = get_users(false); $usersearchcount = get_users(false, '', true, null, "", '', '', '', '', '*', $extrasql, $params); @@ -208,8 +211,27 @@ } $table = new html_table(); - $table->head = array ($fullnamedisplay, $email, $city, $country, $lastaccess, "", "", ""); - $table->align = array ("left", "left", "left", "left", "left", "center", "center", "center"); + $table->head = array (); + $table->align = array(); + $table->head[] = $fullnamedisplay; + $table->align[] = 'left'; + foreach ($extracolumns as $field) { + $table->head[] = ${$field}; + $table->align[] = 'left'; + } + $table->head[] = $city; + $table->align[] = 'left'; + $table->head[] = $country; + $table->align[] = 'left'; + $table->head[] = $lastaccess; + $table->align[] = 'left'; + $table->head[] = ""; + $table->align[] = 'center'; + $table->head[] = ""; + $table->align[] = 'center'; + $table->head[] = ""; + $table->align[] = 'center'; + $table->width = "95%"; foreach ($users as $user) { if (isguestuser($user)) { @@ -272,14 +294,18 @@ } $fullname = fullname($user, true); - $table->data[] = array ("id&course=$site->id\">$fullname", - "$user->email", - "$user->city", - "$user->country", - $strlastaccess, - $editbutton, - $deletebutton, - $confirmbutton); + $row = array (); + $row[] = "id&course=$site->id\">$fullname"; + foreach ($extracolumns as $field) { + $row[] = $user->{$field}; + } + $row[] = $user->city; + $row[] = $user->country; + $row[] = $strlastaccess; + $row[] = $editbutton; + $row[] = $deletebutton; + $row[] = $confirmbutton; + $table->data[] = $row; } } diff --git a/enrol/locallib.php b/enrol/locallib.php index f07975a124d..a2a6a204654 100644 --- a/enrol/locallib.php +++ b/enrol/locallib.php @@ -199,7 +199,9 @@ class course_enrolment_manager { $key = md5("$sort-$direction-$page-$perpage"); if (!array_key_exists($key, $this->users)) { list($instancessql, $params, $filter) = $this->get_instance_sql(); - $ufields = user_picture::fields('u', array('lastaccess', 'email')); + $extrafields = get_extra_user_fields($this->get_context()); + $extrafields[] = 'lastaccess'; + $ufields = user_picture::fields('u', $extrafields); $sql = "SELECT DISTINCT $ufields, ul.timeaccess AS lastseen FROM {user} u JOIN {user_enrolments} ue ON (ue.userid = u.id AND ue.enrolid $instancessql) @@ -279,10 +281,8 @@ class course_enrolment_manager { $tests = array("id <> :guestid", 'u.deleted = 0', 'u.confirmed = 1'); $params = array('guestid' => $CFG->siteguest); if (!empty($search)) { - $conditions = array( - $DB->sql_concat('u.firstname', "' '", 'u.lastname'), - 'u.email' - ); + $conditions = get_extra_user_fields($this->get_context()); + $conditions[] = $DB->sql_concat('u.firstname', "' '", 'u.lastname'); if ($searchanywhere) { $searchparam = '%' . $search . '%'; } else { @@ -298,7 +298,10 @@ class course_enrolment_manager { } $wherecondition = implode(' AND ', $tests); - $ufields = user_picture::fields('u', array('username', 'lastaccess')); + $extrafields = get_extra_user_fields($this->get_context(), array('username', 'lastaccess')); + $extrafields[] = 'username'; + $extrafields[] = 'lastaccess'; + $ufields = user_picture::fields('u', $extrafields); $fields = 'SELECT '.$ufields; $countfields = 'SELECT COUNT(1)'; @@ -835,6 +838,7 @@ class course_enrolment_manager { $canmanagegroups = has_capability('moodle/course:managegroups', $context); $url = new moodle_url($pageurl, $this->get_url_params()); + $extrafields = get_extra_user_fields($context); $userdetails = array(); foreach ($users as $user) { @@ -843,12 +847,14 @@ class course_enrolment_manager { 'courseid' => $courseid, 'picture' => new user_picture($user), 'firstname' => fullname($user, true), - 'email' => $user->email, 'lastseen' => $strnever, 'roles' => array(), 'groups' => array(), 'enrolments' => array() ); + foreach ($extrafields as $field) { + $details[$field] = $user->{$field}; + } if ($user->lastaccess) { $details['lastseen'] = format_time($now - $user->lastaccess); diff --git a/enrol/manual/ajax.php b/enrol/manual/ajax.php index 6f58ee4b0be..a9d5bb7f804 100644 --- a/enrol/manual/ajax.php +++ b/enrol/manual/ajax.php @@ -68,9 +68,16 @@ switch ($action) { $search = optional_param('search', '', PARAM_RAW); $page = optional_param('page', 0, PARAM_INT); $outcome->response = $manager->get_potential_users($enrolid, $search, true, $page); + $extrafields = get_extra_user_fields($context); foreach ($outcome->response['users'] as &$user) { $user->picture = $OUTPUT->user_picture($user); $user->fullname = fullname($user); + $fieldvalues = array(); + foreach ($extrafields as $field) { + $fieldvalues[] = s($user->{$field}); + unset($user->{$field}); + } + $user->extrafields = implode(', ', $fieldvalues); } $outcome->success = true; break; diff --git a/enrol/manual/yui/quickenrolment/quickenrolment.js b/enrol/manual/yui/quickenrolment/quickenrolment.js index 1f266d5675e..9ed9fbbdac9 100644 --- a/enrol/manual/yui/quickenrolment/quickenrolment.js +++ b/enrol/manual/yui/quickenrolment/quickenrolment.js @@ -44,7 +44,7 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) { PICTURE : 'picture', DETAILS : 'details', FULLNAME : 'fullname', - EMAIL : 'email', + EXTRAFIELDS : 'extrafields', OPTIONS : 'options', ODD : 'odd', EVEN : 'even', @@ -344,7 +344,7 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) { .append(create(user.picture))) .append(create('
') .append(create('
'+user.fullname+'
')) - .append(create('
'+user.email+'
'))) + .append(create('
'+user.extrafields+'
'))) .append(create('
') .append(create(''))) ); diff --git a/enrol/renderer.php b/enrol/renderer.php index c387dab8e9f..fafbfd790e3 100644 --- a/enrol/renderer.php +++ b/enrol/renderer.php @@ -417,7 +417,8 @@ class course_enrolment_table extends html_table implements renderable { * @static * @var array */ - protected static $sortablefields = array('firstname', 'lastname', 'email'); + protected static $sortablefields = array('firstname', 'lastname', 'idnumber', 'email', + 'phone1', 'phone2', 'institution', 'department' ); /** * Constructs the table diff --git a/enrol/users.php b/enrol/users.php index ae408ae2c10..8ff9c26c638 100644 --- a/enrol/users.php +++ b/enrol/users.php @@ -166,13 +166,18 @@ if ($action) { $renderer = $PAGE->get_renderer('core_enrol'); +$userdetails = array ( + 'picture' => false, + 'firstname' => get_string('firstname'), + 'lastname' => get_string('lastname'), +); +$extrafields = get_extra_user_fields($context); +foreach ($extrafields as $field) { + $userdetails[$field] = get_user_field_name($field); +} + $fields = array( - 'userdetails' => array ( - 'picture' => false, - 'firstname' => get_string('firstname'), - 'lastname' => get_string('lastname'), - 'email' => get_string('email') - ), + 'userdetails' => $userdetails, 'lastseen' => get_string('lastaccess'), 'role' => get_string('roles', 'role'), 'group' => get_string('groups', 'group'), diff --git a/grade/report/grader/lib.php b/grade/report/grader/lib.php index 1d6fa933478..e9590d2669b 100644 --- a/grade/report/grader/lib.php +++ b/grade/report/grader/lib.php @@ -340,7 +340,8 @@ class grade_report_grader extends grade_report { list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->context); //fields we need from the user table - $userfields = user_picture::fields('u', array('idnumber')); + $userfields = user_picture::fields('u'); + $userfields .= get_extra_user_fields_sql($this->context); $sortjoin = $sort = $params = null; @@ -556,23 +557,20 @@ class grade_report_grader extends grade_report { $rows = array(); $showuserimage = $this->get_pref('showuserimage'); - $showuseridnumber = $this->get_pref('showuseridnumber'); $fixedstudents = $this->is_fixed_students(); $strfeedback = $this->get_lang_string("feedback"); $strgrade = $this->get_lang_string('grade'); - $arrows = $this->get_sort_arrows(); + $extrafields = get_extra_user_fields($this->context); + + $arrows = $this->get_sort_arrows($extrafields); $colspan = 1; - if (has_capability('gradereport/'.$CFG->grade_profilereport.':view', $this->context)) { $colspan++; } - - if ($showuseridnumber) { - $colspan++; - } + $colspan += count($extrafields); $levels = count($this->gtree->levels) - 1; @@ -600,17 +598,14 @@ class grade_report_grader extends grade_report { $headerrow->cells[] = $studentheader; - if ($showuseridnumber) { - // TODO: weird, this is not used anywhere - $sortidnumberlink = html_writer::link(new moodle_url($this->baseurl, array('sortitemid'=>'idnumber')), get_string('idnumber')); + foreach ($extrafields as $field) { + $fieldheader = new html_table_cell(); + $fieldheader->attributes['class'] = 'header userfield user' . $field; + $fieldheader->scope = 'col'; + $fieldheader->header = true; + $fieldheader->text = $arrows[$field]; - $idnumberheader = new html_table_cell(); - $idnumberheader->attributes['class'] = 'header useridnumber'; - $idnumberheader->scope = 'col'; - $idnumberheader->header = true; - $idnumberheader->text = $arrows['idnumber']; - - $headerrow->cells[] = $idnumberheader; + $headerrow->cells[] = $fieldheader; } $rows[] = $headerrow; @@ -661,13 +656,13 @@ class grade_report_grader extends grade_report { $userrow->cells[] = $userreportcell; } - if ($showuseridnumber) { - $idnumbercell = new html_table_cell(); - $idnumbercell->attributes['class'] = 'header useridnumber'; - $idnumbercell->header = true; - $idnumbercell->scope = 'row'; - $idnumbercell->text = $user->idnumber; - $userrow->cells[] = $idnumbercell; + foreach ($extrafields as $field) { + $fieldcell = new html_table_cell(); + $fieldcell->attributes['class'] = 'header userfield user' . $field; + $fieldcell->header = true; + $fieldcell->scope = 'row'; + $fieldcell->text = $user->{$field}; + $userrow->cells[] = $fieldcell; } $rows[] = $userrow; @@ -1205,8 +1200,6 @@ class grade_report_grader extends grade_report { $iconsrow = new html_table_row(); $iconsrow->attributes['class'] = 'controls'; - $showuseridnumber = $this->get_pref('showuseridnumber'); - foreach ($this->gtree->items as $itemid=>$unused) { // emulate grade element $item =& $this->gtree->get_item($itemid); @@ -1588,9 +1581,11 @@ class grade_report_grader extends grade_report { * Refactored function for generating HTML of sorting links with matching arrows. * Returns an array with 'studentname' and 'idnumber' as keys, with HTML ready * to inject into a table header cell. + * @param array $extrafields Array of extra fields being displayed, such as + * user idnumber * @return array An associative array of HTML sorting links+arrows */ - public function get_sort_arrows() { + public function get_sort_arrows(array $extrafields = array()) { global $OUTPUT; $arrows = array(); @@ -1601,7 +1596,6 @@ class grade_report_grader extends grade_report { $firstlink = html_writer::link(new moodle_url($this->baseurl, array('sortitemid'=>'firstname')), $strfirstname); $lastlink = html_writer::link(new moodle_url($this->baseurl, array('sortitemid'=>'lastname')), $strlastname); - $idnumberlink = html_writer::link(new moodle_url($this->baseurl, array('sortitemid'=>'idnumber')), get_string('idnumber')); $arrows['studentname'] = $lastlink; @@ -1623,13 +1617,17 @@ class grade_report_grader extends grade_report { } } - $arrows['idnumber'] = $idnumberlink; + foreach ($extrafields as $field) { + $fieldlink = html_writer::link(new moodle_url($this->baseurl, + array('sortitemid'=>$field)), get_user_field_name($field)); + $arrows[$field] = $fieldlink; - if ('idnumber' == $this->sortitemid) { - if ($this->sortorder == 'ASC') { - $arrows['idnumber'] .= print_arrow('up', $strsortasc, true); - } else { - $arrows['idnumber'] .= print_arrow('down', $strsortdesc, true); + if ($field == $this->sortitemid) { + if ($this->sortorder == 'ASC') { + $arrows[$field] .= print_arrow('up', $strsortasc, true); + } else { + $arrows[$field] .= print_arrow('down', $strsortdesc, true); + } } } diff --git a/grade/report/grader/preferences_form.php b/grade/report/grader/preferences_form.php index 37ed17e1471..535c7aac4d1 100644 --- a/grade/report/grader/preferences_form.php +++ b/grade/report/grader/preferences_form.php @@ -109,7 +109,6 @@ class grader_report_preferences_form extends moodleform { $preferences['prefgeneral']['enableajax'] = $checkbox_default; $preferences['prefshow']['showuserimage'] = $checkbox_default; - $preferences['prefshow']['showuseridnumber'] = $checkbox_default; $preferences['prefshow']['showactivityicons'] = $checkbox_default; $preferences['prefshow']['showranges'] = $checkbox_default; diff --git a/grade/report/grader/settings.php b/grade/report/grader/settings.php index a2acaaf7527..f357e2d1b14 100644 --- a/grade/report/grader/settings.php +++ b/grade/report/grader/settings.php @@ -63,9 +63,6 @@ if ($ADMIN->fulltree) { $settings->add(new admin_setting_configcheckbox('grade_report_showuserimage', get_string('showuserimage', 'grades'), get_string('showuserimage_help', 'grades'), 1)); - $settings->add(new admin_setting_configcheckbox('grade_report_showuseridnumber', get_string('showuseridnumber', 'grades'), - get_string('showuseridnumber_help', 'grades'), 0)); - $settings->add(new admin_setting_configcheckbox('grade_report_showactivityicons', get_string('showactivityicons', 'grades'), get_string('showactivityicons_help', 'grades'), 1)); diff --git a/grade/report/grader/styles.css b/grade/report/grader/styles.css index e897aa4b6df..39ffc6bf6d0 100644 --- a/grade/report/grader/styles.css +++ b/grade/report/grader/styles.css @@ -127,7 +127,7 @@ border-style:solid; border-width:0 0 1px; } -table#user-grades th.useridnumber { +table#user-grades th.userfield { border-style:solid; border-width:0 0 1px 1px; } @@ -529,7 +529,7 @@ border-style:solid; border-width:0; } -table#user-grades td.useridnumber, +table#user-grades td.userfield, table#user-grades th, .path-grade-report-grader div.gradeparent, .path-grade-report-grader .ie6 form, @@ -560,7 +560,7 @@ background-color:#f3ead8; } .path-grade-report-grader table th.user, -.path-grade-report-grader table td.useridnumber { +.path-grade-report-grader table td.userfield { text-align:left; vertical-align:middle; } diff --git a/group/members.php b/group/members.php index 92e4f9a26bc..fd53b135f03 100644 --- a/group/members.php +++ b/group/members.php @@ -34,9 +34,7 @@ if ($cancel) { } $groupmembersselector = new group_members_selector('removeselect', array('groupid' => $groupid, 'courseid' => $course->id)); -$groupmembersselector->set_extra_fields(array()); $potentialmembersselector = new group_non_members_selector('addselect', array('groupid' => $groupid, 'courseid' => $course->id)); -$potentialmembersselector->set_extra_fields(array()); if (optional_param('add', false, PARAM_BOOL) && confirm_sesskey()) { $userstoadd = $potentialmembersselector->get_selected_users(); diff --git a/lang/en/admin.php b/lang/en/admin.php index 14d9d337811..f554e6b0cf4 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -202,7 +202,6 @@ $string['configenablewsdocumentation'] = 'Enable auto-generation of web services $string['configerrorlevel'] = 'Choose the amount of PHP warnings that you want to be displayed. Normal is usually the best choice.'; $string['configextendedusernamechars'] = 'Enable this setting to allow students to use any characters in their usernames (note this does not affect their actual names). The default is "false" which restricts usernames to be alphanumeric lowercase characters, underscore (_), hyphen (-), period (.) or at symbol (@).'; $string['configextramemorylimit'] = 'Some scripts like search, backup/restore or cron require more memory. Set higher values for large sites.'; -$string['configextrauserselectorfields'] = 'Select which fields are searched and displayed, in addition to full names, when selecting users, for example when assigning roles or when adding users to a group. For security reasons, it is recommended that the username field is NOT selected.'; $string['configfilterall'] = 'Filter all strings, including headings, titles, navigation bar and so on. This is mostly useful when using the multilang filter, otherwise it will just create extra load on your site for little gain.'; $string['configfiltermatchoneperpage'] = 'Automatic linking filters will only generate a single link for the first matching text instance found on the complete page. All others are ignored.'; $string['configfiltermatchonepertext'] = 'Automatic linking filters will only generate a single link for the first matching text instance found in each item of text (e.g., resource, block) on the page. All others are ignored. This setting is ignored if the one per page setting is yes.'; @@ -504,7 +503,6 @@ $string['experimental'] = 'Experimental'; $string['experimentalsettings'] = 'Experimental settings'; $string['extendedusernamechars'] = 'Allow extended characters in usernames'; $string['extramemorylimit'] = 'Extra PHP memory limit'; -$string['extrauserselectorfields'] = 'When selecting users, search and display'; $string['fatalmagicquotesruntime'] = '

Serious configuration error detected, please notify server administrator.

To operate properly, Moodle requires that administrator changes PHP settings.

magic_quotes_runtime must be set to off.

This setting is controlled by editing php.ini, Apache/IIS
configuration or .htaccess file on the server.

'; $string['fatalsessionautostart'] = '

Serious configuration error detected, please notify server administrator.

To operate properly, Moodle requires that administrator changes PHP settings.

session.auto_start must be set to off.

This setting is controlled by editing php.ini, Apache/IIS
configuration or .htaccess file on the server.

'; $string['filecreated'] = 'New file created'; @@ -884,6 +882,8 @@ $string['settingmemorylimit'] = 'Insufficient memory detected, please set higher $string['settingsafemode'] = 'Moodle is not fully compatible with safe mode, please ask server administrator to turn it off. Running Moodle under safe mode is not supported, please expect various problems if you do so.'; $string['showcommentscount'] = 'Show comments count'; $string['showdetails'] = 'Show details'; +$string['showuseridentity'] = 'Show user identity'; +$string['showuseridentity_desc'] = 'When selecting or searching for users, and when displaying lists of users, these fields may be shown in addition to their full name. The fields are only shown to users who have the moodle/site:viewuseridentity capability; by default, teachers and managers. (This option makes most sense if you choose one or two fields that are mandatory at your institution.)';$string['simpletest'] = 'Unit tests'; $string['simplexmlrequired'] = 'The SimpleXML PHP extension is now required by Moodle.'; $string['sitemaintenance'] = 'The site is undergoing maintenance and is currently not available'; $string['sitemaintenancemode'] = 'Maintenance mode'; diff --git a/lang/en/grades.php b/lang/en/grades.php index 94d132ccd56..0b271bb7432 100644 --- a/lang/en/grades.php +++ b/lang/en/grades.php @@ -581,8 +581,6 @@ $string['showranges'] = 'Show ranges'; $string['showranges_help'] = 'If enabled, the grader report will contain an additional row displaying the range for each category and grade item.'; $string['showrank'] = 'Show rank'; $string['showrank_help'] = 'Show the position of the student in relation to the rest of the class for each grade item?'; -$string['showuseridnumber'] = 'Show user ID numbers'; -$string['showuseridnumber_help'] = 'If enabled, user ID numbers are shown in an additional column.'; $string['showuserimage'] = 'Show user profile images'; $string['showuserimage_help'] = 'Whether to show the user\'s profile image next to the name in the grader report.'; $string['showverbose'] = 'Show {$a->category} {$a->itemmodule} {$a->itemname}'; diff --git a/lang/en/role.php b/lang/en/role.php index bda249f5612..35fc81f1ca1 100644 --- a/lang/en/role.php +++ b/lang/en/role.php @@ -334,6 +334,7 @@ $string['site:uploadusers'] = 'Upload new users from file'; $string['site:viewfullnames'] = 'Always see full names of users'; $string['site:viewparticipants'] = 'View participants'; $string['site:viewreports'] = 'View reports'; +$string['site:viewuseridentity'] = 'See full user identity in lists'; $string['tag:create'] = 'Create new tags'; $string['tag:edit'] = 'Edit existing tags'; $string['tag:editblocks'] = 'Edit blocks in tags pages'; diff --git a/lib/completionlib.php b/lib/completionlib.php index cce41d0d922..b8d9df60495 100644 --- a/lib/completionlib.php +++ b/lib/completionlib.php @@ -1057,10 +1057,12 @@ class completion_info { * @param string $sort Order by clause (optional) * @param integer $limitfrom Result start (optional) * @param integer $limitnum Result max size (optional) + * @param context $extracontext If set, includes extra user information fields + * as appropriate to display for current user in this context * @return array */ function get_tracked_users($where = '', $where_params = array(), $groupid = 0, - $sort = '', $limitfrom = '', $limitnum = '') { + $sort = '', $limitfrom = '', $limitnum = '', context $extracontext = null) { global $DB; @@ -1074,6 +1076,9 @@ class completion_info { u.lastname, u.idnumber "; + if ($extracontext) { + $sql .= get_extra_user_fields_sql($extracontext, 'u', '', array('idnumber')); + } $sql .= $tracked->sql; @@ -1190,16 +1195,19 @@ class completion_info { * @param int $groupid Group ID or 0 (default)/false for all groups * @param int $pagesize Number of users to actually return (optional) * @param int $start User to start at if paging (optional) + * @param context $extracontext If set, includes extra user information fields + * as appropriate to display for current user in this context * @return Object with ->total and ->start (same as $start) and ->users; * an array of user objects (like mdl_user id, firstname, lastname) * containing an additional ->progress array of coursemoduleid => completionstate */ public function get_progress_all($where = '', $where_params = array(), $groupid = 0, - $sort = '', $pagesize = '', $start = '') { + $sort = '', $pagesize = '', $start = '', context $extracontext = null) { global $CFG, $DB; // Get list of applicable users - $users = $this->get_tracked_users($where, $where_params, $groupid, $sort, $start, $pagesize); + $users = $this->get_tracked_users($where, $where_params, $groupid, $sort, + $start, $pagesize, $extracontext); // Get progress information for these users in groups of 1, 000 (if needed) // to avoid making the SQL IN too long diff --git a/lib/datalib.php b/lib/datalib.php index d6b09887c6c..285729c23c3 100644 --- a/lib/datalib.php +++ b/lib/datalib.php @@ -249,11 +249,13 @@ function get_users($get=true, $search='', $confirmed=false, array $exceptions=nu * @param string $lastinitial Users whose last name starts with $lastinitial * @param string $extraselect An additional SQL select statement to append to the query * @param array $extraparams Additional parameters to use for the above $extraselect + * @param object $extracontext If specified, will include user 'extra fields' + * as appropriate for current user and given context * @return array Array of {@link $USER} records */ - function get_users_listing($sort='lastaccess', $dir='ASC', $page=0, $recordsperpage=0, - $search='', $firstinitial='', $lastinitial='', $extraselect='', array $extraparams=null) { + $search='', $firstinitial='', $lastinitial='', $extraselect='', + array $extraparams=null, $extracontext = null) { global $DB; $fullname = $DB->sql_fullname(); @@ -289,8 +291,18 @@ function get_users_listing($sort='lastaccess', $dir='ASC', $page=0, $recordsperp $sort = " ORDER BY $sort $dir"; } -/// warning: will return UNCONFIRMED USERS - return $DB->get_records_sql("SELECT id, username, email, firstname, lastname, city, country, lastaccess, confirmed, mnethostid + // If a context is specified, get extra user fields that the current user + // is supposed to see. + $extrafields = ''; + if ($extracontext) { + $extrafields = get_extra_user_fields_sql($extracontext, '', '', + array('id', 'username', 'email', 'firstname', 'lastname', 'city', 'country', + 'lastaccess', 'confirmed', 'mnethostid')); + } + + // warning: will return UNCONFIRMED USERS + return $DB->get_records_sql("SELECT id, username, email, firstname, lastname, city, country, + lastaccess, confirmed, mnethostid$extrafields FROM {user} WHERE $select $sort", $params, $page, $recordsperpage); diff --git a/lib/db/access.php b/lib/db/access.php index 667e4b2d77c..1ec43820a3e 100644 --- a/lib/db/access.php +++ b/lib/db/access.php @@ -385,6 +385,20 @@ $capabilities = array( ) ), + // In reports that give lists of users, extra information about each user's + // identity (the fields configured in site option showuseridentity) will be + // displayed to users who have this capability. + 'moodle/site:viewuseridentity' => array( + + 'captype' => 'read', + 'contextlevel' => CONTEXT_COURSE, + 'archetypes' => array( + 'teacher' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + 'manager' => CAP_ALLOW + ) + ), + 'moodle/site:viewreports' => array( 'riskbitmask' => RISK_PERSONAL, diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index 647f27d5db4..283948419fe 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -6839,6 +6839,17 @@ FROM upgrade_main_savepoint(true, 2011102700.01); } + if ($oldversion < 2011110200.01) { + // Rename 'extrauserselectorfields' to 'showuseridentity' as it is + // being used more widely + if (isset($CFG->extrauserselectorfields)) { + set_config('showuseridentity', $CFG->extrauserselectorfields); + unset_config('extrauserselectorfields'); + } + unset_config('grade_report_showuseridnumber'); + upgrade_main_savepoint(true, 2011110200.01); + } + return true; } diff --git a/lib/moodlelib.php b/lib/moodlelib.php index bba54189b4b..6f4bbd26da3 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -3339,6 +3339,88 @@ function fullname($user, $override=false) { return get_string('fullnamedisplay', '', $user); } +/** + * Checks if current user is shown any extra fields when listing users. + * @param object $context Context + * @param array $already Array of fields that we're going to show anyway + * so don't bother listing them + * @return array Array of field names from user table, not including anything + * listed in $already + */ +function get_extra_user_fields($context, $already = array()) { + global $CFG; + + // Only users with permission get the extra fields + if (!has_capability('moodle/site:viewuseridentity', $context)) { + return array(); + } + + // Split showuseridentity on comma + if ($CFG->showuseridentity === '') { + // Explode gives wrong result with empty string + $extra = array(); + } else { + $extra = explode(',', $CFG->showuseridentity); + } + $renumber = false; + foreach ($extra as $key => $field) { + if (in_array($field, $already)) { + unset($extra[$key]); + $renumber = true; + } + } + if ($renumber) { + // For consistency, if entries are removed from array, renumber it + // so they are numbered as you would expect + $extra = array_merge($extra); + } + return $extra; +} + +/** + * If the current user is to be shown extra user fields when listing or + * selecting users, returns a string suitable for including in an SQL select + * clause to retrieve those fields. + * @param object $context Context + * @param string $alias Alias of user table, e.g. 'u' (default none) + * @param string $prefix Prefix for field names using AS, e.g. 'u_' (default none) + * @param array $already Array of fields that we're going to include anyway + * so don't list them (default none) + * @return string Partial SQL select clause, beginning with comma, for example + * ',u.idnumber,u.department' unless it is blank + */ +function get_extra_user_fields_sql($context, $alias='', $prefix='', + $already = array()) { + $fields = get_extra_user_fields($context, $already); + $result = ''; + // Add punctuation for alias + if ($alias !== '') { + $alias .= '.'; + } + foreach ($fields as $field) { + $result .= ', ' . $alias . $field; + if ($prefix) { + $result .= ' AS ' . $prefix . $field; + } + } + return $result; +} + +/** + * Returns the display name of a field in the user table. Works for most fields + * that are commonly displayed to users. + * @param string $field Field name, e.g. 'phone1' + * @return string Text description taken from language file, e.g. 'Phone number' + */ +function get_user_field_name($field) { + // Some fields have language strings which are not the same as field name + switch ($field) { + case 'phone1' : return get_string('phone'); + } + // Otherwise just use the same lang string + return get_string($field); +} + /** * Returns whether a given authentication plugin exists. * diff --git a/lib/simpletest/testmoodlelib.php b/lib/simpletest/testmoodlelib.php index fed0767a061..d0070546638 100644 --- a/lib/simpletest/testmoodlelib.php +++ b/lib/simpletest/testmoodlelib.php @@ -1203,6 +1203,81 @@ class moodlelib_test extends UnitTestCase { } } + public function test_get_extra_user_fields() { + global $CFG; + $oldshowuseridentity = $CFG->showuseridentity; + + // It would be really nice if there were a way to 'mock' has_capability + // checks (either to return true or false) but as there is not, this + // test doesn't test the capability check. Presumably, anyone running + // unit tests will have the capability. + $context = context_system::instance(); + + // No fields + $CFG->showuseridentity = ''; + $this->assertEqual(array(), get_extra_user_fields($context)); + + // One field + $CFG->showuseridentity = 'frog'; + $this->assertEqual(array('frog'), get_extra_user_fields($context)); + + // Two fields + $CFG->showuseridentity = 'frog,zombie'; + $this->assertEqual(array('frog', 'zombie'), get_extra_user_fields($context)); + + // No fields, except + $CFG->showuseridentity = ''; + $this->assertEqual(array(), get_extra_user_fields($context, array('frog'))); + + // One field + $CFG->showuseridentity = 'frog'; + $this->assertEqual(array(), get_extra_user_fields($context, array('frog'))); + + // Two fields + $CFG->showuseridentity = 'frog,zombie'; + $this->assertEqual(array('zombie'), get_extra_user_fields($context, array('frog'))); + + // As long as this test passes, the value will be set back. This is only + // in-memory anyhow + $CFG->showuseridentity = $oldshowuseridentity; + } + + public function test_get_extra_user_fields_sql() { + global $CFG; + $oldshowuseridentity = $CFG->showuseridentity; + $context = context_system::instance(); + + // No fields + $CFG->showuseridentity = ''; + $this->assertEqual('', get_extra_user_fields_sql($context)); + + // One field + $CFG->showuseridentity = 'frog'; + $this->assertEqual(', frog', get_extra_user_fields_sql($context)); + + // Two fields with table prefix + $CFG->showuseridentity = 'frog,zombie'; + $this->assertEqual(', u1.frog, u1.zombie', get_extra_user_fields_sql($context, 'u1')); + + // Two fields with field prefix + $CFG->showuseridentity = 'frog,zombie'; + $this->assertEqual(', frog AS u_frog, zombie AS u_zombie', + get_extra_user_fields_sql($context, '', 'u_')); + + // One field excluded + $CFG->showuseridentity = 'frog'; + $this->assertEqual('', get_extra_user_fields_sql($context, '', '', array('frog'))); + + // Two fields, one excluded, table+field prefix + $CFG->showuseridentity = 'frog,zombie'; + $this->assertEqual(', u1.zombie AS u_zombie', + get_extra_user_fields_sql($context, 'u1', 'u_', array('frog'))); + + // As long as this test passes, the value will be set back. This is only + // in-memory anyhow + $CFG->showuseridentity = $oldshowuseridentity; + } + public function test_userdate() { global $USER, $CFG; diff --git a/mod/assignment/lib.php b/mod/assignment/lib.php index 26a3bf70a85..a3d5ca23d7b 100644 --- a/mod/assignment/lib.php +++ b/mod/assignment/lib.php @@ -1240,19 +1240,28 @@ class assignment_base { } } - $tablecolumns = array('picture', 'fullname', 'grade', 'submissioncomment', 'timemodified', 'timemarked', 'status', 'finalgrade'); + $extrafields = get_extra_user_fields($context); + $tablecolumns = array_merge(array('picture', 'fullname'), $extrafields, + array('grade', 'submissioncomment', 'timemodified', 'timemarked', 'status', 'finalgrade')); if ($uses_outcomes) { $tablecolumns[] = 'outcome'; // no sorting based on outcomes column } - $tableheaders = array('', - get_string('fullnameuser'), - get_string('grade'), - get_string('comment', 'assignment'), - get_string('lastmodified').' ('.get_string('submission', 'assignment').')', - get_string('lastmodified').' ('.get_string('grade').')', - get_string('status'), - get_string('finalgrade', 'grades')); + $extrafieldnames = array(); + foreach ($extrafields as $field) { + $extrafieldnames[] = get_user_field_name($field); + } + $tableheaders = array_merge( + array('', get_string('fullnameuser')), + $extrafieldnames, + array( + get_string('grade'), + get_string('comment', 'assignment'), + get_string('lastmodified').' ('.get_string('submission', 'assignment').')', + get_string('lastmodified').' ('.get_string('grade').')', + get_string('status'), + get_string('finalgrade', 'grades'), + )); if ($uses_outcomes) { $tableheaders[] = get_string('outcome', 'grades'); } @@ -1273,6 +1282,9 @@ class assignment_base { $table->column_class('picture', 'picture'); $table->column_class('fullname', 'fullname'); + foreach ($extrafields as $field) { + $table->column_class($field, $field); + } $table->column_class('grade', 'grade'); $table->column_class('submissioncomment', 'comment'); $table->column_class('timemodified', 'timemodified'); @@ -1313,7 +1325,7 @@ class assignment_base { $sort = ' ORDER BY '.$sort; } - $ufields = user_picture::fields('u'); + $ufields = user_picture::fields('u', $extrafields); if (!empty($users)) { $select = "SELECT $ufields, s.id AS submissionid, s.grade, s.submissioncomment, @@ -1475,7 +1487,13 @@ class assignment_base { } $userlink = '' . fullname($auser, has_capability('moodle/site:viewfullnames', $this->context)) . ''; - $row = array($picture, $userlink, $grade, $comment, $studentmodified, $teachermodified, $status, $finalgrade); + $extradata = array(); + foreach ($extrafields as $field) { + $extradata[] = $auser->{$field}; + } + $row = array_merge(array($picture, $userlink), $extradata, + array($grade, $comment, $studentmodified, $teachermodified, + $status, $finalgrade)); if ($uses_outcomes) { $row[] = $outcomes; } diff --git a/mod/forum/lib.php b/mod/forum/lib.php index e046dfdad4c..a3f28f1a395 100644 --- a/mod/forum/lib.php +++ b/mod/forum/lib.php @@ -7478,6 +7478,7 @@ abstract class forum_subscriber_selector_base extends user_selector_base { * @param array $options */ public function __construct($name, $options) { + $options['accesscontext'] = $options['context']; parent::__construct($name, $options); if (isset($options['context'])) { $this->context = $options['context']; @@ -8074,4 +8075,4 @@ function forum_get_posts_by_user($user, array $courses, $musthaveaccess = false, } return $return; -} \ No newline at end of file +} diff --git a/mod/quiz/report/attemptsreport.php b/mod/quiz/report/attemptsreport.php index 4a4698f2b97..89bfefc1fc5 100644 --- a/mod/quiz/report/attemptsreport.php +++ b/mod/quiz/report/attemptsreport.php @@ -152,6 +152,9 @@ abstract class quiz_attempt_report extends quiz_default_report { $fields .= "\n(CASE WHEN $qmsubselect THEN 1 ELSE 0 END) AS gradedattempt,"; } + $extrafields = get_extra_user_fields_sql($this->context, 'u', '', + array('id', 'idnumber', 'firstname', 'lastname', 'picture', + 'imagealt', 'institution', 'department', 'email')); $fields .= ' quiza.uniqueid AS usageid, quiza.id AS attempt, @@ -163,7 +166,7 @@ abstract class quiz_attempt_report extends quiz_default_report { u.imagealt, u.institution, u.department, - u.email, + u.email' . $extrafields . ', quiza.sumgrades, quiza.timefinish, quiza.timestart, @@ -239,9 +242,13 @@ abstract class quiz_attempt_report extends quiz_default_report { $headers[] = get_string('firstname'); } - if ($CFG->grade_report_showuseridnumber) { - $columns[] = 'idnumber'; - $headers[] = get_string('idnumber'); + // When downloading, some extra fields are always displayed (because + // there's no space constraint) so do not include in extra-field list + $extrafields = get_extra_user_fields($this->context, + $table->is_downloading() ? array('institution', 'department', 'email') : array()); + foreach ($extrafields as $field) { + $columns[] = $field; + $headers[] = get_user_field_name($field); } if ($table->is_downloading()) { diff --git a/mod/scorm/report/basic/report.php b/mod/scorm/report/basic/report.php index ae3f86a52ce..5cd4c1b2787 100644 --- a/mod/scorm/report/basic/report.php +++ b/mod/scorm/report/basic/report.php @@ -98,8 +98,8 @@ class scorm_basic_report extends scorm_default_report { if ( !$nostudents ) { // Now check if asked download of data + $coursecontext = context_course::instance($course->id); if ($download) { - $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); $shortname = format_string($course->shortname, true, array('context' => $coursecontext)); $filename = clean_filename("$shortname ".format_string($scorm->name, true)); } @@ -117,10 +117,12 @@ class scorm_basic_report extends scorm_default_report { } $columns[]= 'fullname'; $headers[]= get_string('name'); - if ($CFG->grade_report_showuseridnumber) { - $columns[]= 'idnumber'; - $headers[]= get_string('idnumber'); + $extrafields = get_extra_user_fields($coursecontext); + foreach ($extrafields as $field) { + $columns[] = $field; + $headers[] = get_user_field_name($field); } + $columns[]= 'attempt'; $headers[]= get_string('attempt', 'scorm'); $columns[]= 'start'; @@ -153,7 +155,12 @@ class scorm_basic_report extends scorm_default_report { $table->column_suppress('picture'); $table->column_suppress('fullname'); - $table->column_suppress('idnumber'); + // I wonder why it is doing all this suppress malarkey? + // However, if it was suppressing idnumber field before, I guess + // it needs to suppress all the user identity fields now + foreach ($extrafields as $field) { + $table->column_suppress($field); + } $table->no_sorting('start'); $table->no_sorting('finish'); @@ -266,7 +273,8 @@ class scorm_basic_report extends scorm_default_report { // Construct the SQL $select = 'SELECT DISTINCT '.$DB->sql_concat('u.id', '\'#\'', 'COALESCE(st.attempt, 0)').' AS uniqueid, '; $select .= 'st.scormid AS scormid, st.attempt AS attempt, ' . - 'u.id AS userid, u.idnumber, u.firstname, u.lastname, u.picture, u.imagealt, u.email '; + 'u.id AS userid, u.idnumber, u.firstname, u.lastname, u.picture, u.imagealt, u.email' . + get_extra_user_fields_sql($coursecontext, 'u', '', array('idnumber')) . ' '; // This part is the same for all cases - join users and scorm_scoes_track tables $from = 'FROM {user} u '; @@ -387,8 +395,8 @@ class scorm_basic_report extends scorm_default_report { } else { $row[] = fullname($scouser); } - if (in_array('idnumber', $columns)) { - $row[] = $scouser->idnumber; + foreach ($extrafields as $field) { + $row[] = s($scouser->{$field}); } if (empty($timetracks->start)) { $row[] = '-'; diff --git a/report/completion/index.php b/report/completion/index.php index e8708dbed4b..dcd81a98b01 100644 --- a/report/completion/index.php +++ b/report/completion/index.php @@ -45,6 +45,7 @@ $edituser = optional_param('edituser', 0, PARAM_INT); $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST); +$context = context_course::instance($course->id); $url = new moodle_url('/report/completion/index.php', array('course'=>$course->id)); $PAGE->set_url($url); @@ -59,8 +60,9 @@ $start = optional_param('start', 0, PARAM_INT); $sifirst = optional_param('sifirst', 'all', PARAM_ALPHA); $silast = optional_param('silast', 'all', PARAM_ALPHA); -// Whether to show idnumber -$idnumbers = $CFG->grade_report_showuseridnumber; +// Whether to show extra user identity information +$extrafields = get_extra_user_fields($context); +$leftcols = 1 + count($extrafields); // Function for quoting csv cell values function csv_quote($value) { @@ -77,7 +79,6 @@ function csv_quote($value) { // Check permissions require_login($course); -$context=get_context_instance(CONTEXT_COURSE, $course->id); require_capability('report/completion:view', $context); // Get group mode @@ -221,7 +222,8 @@ if ($total) { $group, $firstnamesort ? 'u.firstname ASC' : 'u.lastname ASC', $csv ? 0 : COMPLETION_REPORT_PAGE, - $csv ? 0 : $start + $csv ? 0 : $start, + $context ); } @@ -337,7 +339,8 @@ if (!$csv) { // Print criteria group names print PHP_EOL.''; - print ''.get_string('criteriagroup', 'completion').''; + echo '' . + get_string('criteriagroup', 'completion') . ''; $current_group = false; $col_count = 0; @@ -371,7 +374,8 @@ if (!$csv) { // Print aggregation methods print PHP_EOL.''; - print ''.get_string('aggregationmethod', 'completion').''; + echo '' . + get_string('aggregationmethod', 'completion').''; $current_group = false; $col_count = 0; @@ -430,7 +434,8 @@ if (!$csv) { if (COMPLETION_REPORT_COL_TITLES) { print PHP_EOL.''; - print ''.get_string('criteria', 'completion').''; + echo '' . + get_string('criteria', 'completion') . ''; foreach ($criteria as $criterion) { // Get criteria details @@ -468,9 +473,10 @@ if (!$csv) { print ''; - // Print user id number column - if ($idnumbers) { - print ''.get_string('idnumber').''; + // Print user identity columns + foreach ($extrafields as $field) { + echo '' . + get_user_field_name($field) . ''; } /// @@ -539,10 +545,7 @@ if (!$csv) { } else { - // TODO - if ($idnumbers) { - print $sep; - } + // The CSV file does not contain any headers } @@ -554,16 +557,16 @@ foreach ($progress as $user) { // User name if ($csv) { print csv_quote(fullname($user)); - if ($idnumbers) { - print $sep.csv_quote($user->idnumber); + foreach ($extrafields as $field) { + echo $sep . csv_quote($user->{$field}); } } else { print PHP_EOL.''; print ''.fullname($user).''; - if ($idnumbers) { - print ''.htmlspecialchars($user->idnumber).''; + foreach ($extrafields as $field) { + echo '' . s($user->{$field}) . ''; } } diff --git a/report/progress/index.php b/report/progress/index.php index f14d6649e67..644d8c3f0e9 100644 --- a/report/progress/index.php +++ b/report/progress/index.php @@ -34,6 +34,7 @@ $course = $DB->get_record('course',array('id'=>$id)); if (!$course) { print_error('invalidcourseid'); } +$context = context_course::instance($course->id); // Sort (default lastname, optionally firstname) $sort = optional_param('sort','',PARAM_ALPHA); @@ -50,11 +51,9 @@ $sifirst = optional_param('sifirst', 'all', PARAM_ALPHA); $silast = optional_param('silast', 'all', PARAM_ALPHA); $start = optional_param('start', 0, PARAM_INT); -// Whether to show idnumber -// TODO: This should really not be using a config option 'intended' for -// gradebook, but that option is also used in quiz reports as well. There ought -// to be a generic option somewhere. -$idnumbers = $CFG->grade_report_showuseridnumber; +// Whether to show extra user identity information +$extrafields = get_extra_user_fields($context); +$leftcols = 1 + count($extrafields); function csv_quote($value) { global $excel; @@ -82,7 +81,6 @@ $PAGE->set_pagelayout('report'); require_login($course); // Check basic permission -$context = get_context_instance(CONTEXT_COURSE,$course->id); require_capability('report/progress:view',$context); // Get group mode @@ -127,7 +125,8 @@ if ($total) { $group, $firstnamesort ? 'u.firstname ASC' : 'u.lastname ASC', $csv ? 0 : COMPLETION_REPORT_PAGE, - $csv ? 0 : $start + $csv ? 0 : $start, + $context ); } @@ -300,13 +299,14 @@ if (!$csv) { } print ''; - if ($idnumbers) { - print ''.get_string('idnumber').''; + // Print user identity columns + foreach ($extrafields as $field) { + echo '' . + get_user_field_name($field) . ''; } - } else { - if ($idnumbers) { - print $sep; + foreach ($extrafields as $field) { + echo $sep . csv_quote(get_user_field_name($field)); } } @@ -351,14 +351,14 @@ foreach($progress as $user) { // User name if ($csv) { print csv_quote(fullname($user)); - if ($idnumbers) { - print $sep.csv_quote($user->idnumber); + foreach ($extrafields as $field) { + echo $sep . csv_quote($user->{$field}); } } else { print ''.fullname($user).''; - if ($idnumbers) { - print ''.htmlspecialchars($user->idnumber).''; + foreach ($extrafields as $field) { + echo '' . s($user->{$field}) . ''; } } diff --git a/theme/base/style/core.css b/theme/base/style/core.css index b063edd08c0..76c8b96ce29 100644 --- a/theme/base/style/core.css +++ b/theme/base/style/core.css @@ -361,7 +361,8 @@ table.mod_index {width:100%;} */ .completion-expired {background:#FFDDDD;} .completion-expected {font-size:0.75em;} -.completion-sortchoice {font-size:0.75em;vertical-align:bottom;} +.completion-sortchoice, +.completion-identifyfield {font-size:0.75em;vertical-align:bottom;} .completion-progresscell {text-align:right;} .completion-expired .completion-expected {font-weight:bold;} diff --git a/user/index.php b/user/index.php index f54a5d24962..972364d897d 100644 --- a/user/index.php +++ b/user/index.php @@ -318,7 +318,14 @@ /// Define a table showing a list of users in the current role selection $tablecolumns = array('userpic', 'fullname'); + $extrafields = get_extra_user_fields($context); $tableheaders = array(get_string('userpic'), get_string('fullnameuser')); + if ($mode === MODE_BRIEF) { + foreach ($extrafields as $field) { + $tablecolumns[] = $field; + $tableheaders[] = get_user_field_name($field); + } + } if ($mode === MODE_BRIEF && !isset($hiddenfields['city'])) { $tablecolumns[] = 'city'; $tableheaders[] = get_string('city'); @@ -338,7 +345,6 @@ } $table = new flexible_table('user-index-participants-'.$course->id); - $table->define_columns($tablecolumns); $table->define_headers($tableheaders); $table->define_baseurl($baseurl->out()); @@ -373,11 +379,15 @@ $joins = array("FROM {user} u"); $wheres = array(); + $extrasql = get_extra_user_fields_sql($context, 'u', '', array( + 'id', 'username', 'firstname', 'lastname', 'email', 'city', 'country', + 'picture', 'lang', 'timezone', 'maildisplay', 'imagealt', 'lastaccess')); + if ($isfrontpage) { $select = "SELECT u.id, u.username, u.firstname, u.lastname, u.email, u.city, u.country, u.picture, u.lang, u.timezone, u.maildisplay, u.imagealt, - u.lastaccess"; + u.lastaccess$extrasql"; $joins[] = "JOIN ($esql) e ON e.id = u.id"; // everybody on the frontpage usually if ($accesssince) { $wheres[] = get_user_lastaccess_sql($accesssince); @@ -387,7 +397,7 @@ $select = "SELECT u.id, u.username, u.firstname, u.lastname, u.email, u.city, u.country, u.picture, u.lang, u.timezone, u.maildisplay, u.imagealt, - COALESCE(ul.timeaccess, 0) AS lastaccess"; + COALESCE(ul.timeaccess, 0) AS lastaccess$extrasql"; $joins[] = "JOIN ($esql) e ON e.id = u.id"; // course enrolled users only $joins[] = "LEFT JOIN {user_lastaccess} ul ON (ul.userid = u.id AND ul.courseid = :courseid)"; // not everybody accessed course yet $params['courseid'] = $course->id; @@ -607,9 +617,20 @@ $row->cells[1]->text .= get_string('role').get_string('labelsep', 'langconfig').$user->role.'
'; } if ($user->maildisplay == 1 or ($user->maildisplay == 2 and ($course->id != SITEID) and !isguestuser()) or - has_capability('moodle/course:viewhiddenuserfields', $context)) { + has_capability('moodle/course:viewhiddenuserfields', $context) or + in_array('email', $extrafields)) { $row->cells[1]->text .= get_string('email').get_string('labelsep', 'langconfig').html_writer::link("mailto:$user->email", $user->email) . '
'; } + foreach ($extrafields as $field) { + if ($field === 'email') { + // Skip email because it was displayed with different + // logic above (because this page is intended for + // students too) + continue; + } + $row->cells[1]->text .= get_user_field_name($field) . + get_string('labelsep', 'langconfig') . s($user->{$field}) . '
'; + } if (($user->city or $user->country) and (!isset($hiddenfields['city']) or !isset($hiddenfields['country']))) { $row->cells[1]->text .= get_string('city').get_string('labelsep', 'langconfig'); if ($user->city && !isset($hiddenfields['city'])) { @@ -717,6 +738,11 @@ $data = array ($OUTPUT->user_picture($user, array('size' => 35, 'courseid'=>$course->id)), $profilelink); + if ($mode === MODE_BRIEF) { + foreach ($extrafields as $field) { + $data[] = $user->{$field}; + } + } if ($mode === MODE_BRIEF && !isset($hiddenfields['city'])) { $data[] = $user->city; } @@ -752,7 +778,6 @@ $data[] = ''; } $table->add_data($data); - } } diff --git a/user/selector/lib.php b/user/selector/lib.php index 89bf61662b8..9dd55f63004 100644 --- a/user/selector/lib.php +++ b/user/selector/lib.php @@ -40,6 +40,9 @@ abstract class user_selector_base { protected $name; /** @var array Extra fields to search on and return in addition to firstname and lastname. */ protected $extrafields; + /** @var object Context used for capability checks regarding this selector (does + * not necessarily restrict user list) */ + protected $accesscontext; /** @var boolean Whether the conrol should allow selection of many users, or just one. */ protected $multiselect = true; /** @var int The height this control should have, in rows. */ @@ -89,10 +92,20 @@ abstract class user_selector_base { // Initialise member variables from constructor arguments. $this->name = $name; + + // Use specified context for permission checks, system context if not + // specified + if (isset($options['accesscontext'])) { + $this->accesscontext = $options['accesscontext']; + } else { + $this->accesscontext = get_context_instance(CONTEXT_SYSTEM); + } + if (isset($options['extrafields'])) { $this->extrafields = $options['extrafields']; - } else if (!empty($CFG->extrauserselectorfields)) { - $this->extrafields = explode(',', $CFG->extrauserselectorfields); + } else if (!empty($CFG->showuseridentity) && + has_capability('moodle/site:viewuseridentity', $this->accesscontext)) { + $this->extrafields = explode(',', $CFG->showuseridentity); } else { $this->extrafields = array(); } @@ -331,7 +344,8 @@ abstract class user_selector_base { 'name' => $this->name, 'exclude' => $this->exclude, 'extrafields' => $this->extrafields, - 'multiselect' => $this->multiselect + 'multiselect' => $this->multiselect, + 'accesscontext' => $this->accesscontext, ); } @@ -580,13 +594,15 @@ abstract class user_selector_base { * @return string a string representation of the user. */ public function output_user($user) { - $bits = array( - fullname($user) - ); - foreach ($this->extrafields as $field) { - $bits[] = $user->$field; + $out = fullname($user); + if ($this->extrafields) { + $displayfields = array(); + foreach ($this->extrafields as $field) { + $displayfields[] = $user->{$field}; + } + $out .= ' (' . implode(', ', $displayfields) . ')'; } - return implode(', ', $bits); + return $out; } /** @@ -660,6 +676,7 @@ abstract class groups_user_selector_base extends user_selector_base { */ public function __construct($name, $options) { global $CFG; + $options['accesscontext'] = get_context_instance(CONTEXT_COURSE, $options['courseid']); parent::__construct($name, $options); $this->groupid = $options['groupid']; $this->courseid = $options['courseid']; diff --git a/version.php b/version.php index 09272926595..9b858c2a464 100644 --- a/version.php +++ b/version.php @@ -30,8 +30,7 @@ defined('MOODLE_INTERNAL') || die(); - -$version = 2011110200.00; // YYYYMMDD = weekly release date of this DEV branch +$version = 2011110200.01; // YYYYMMDD = weekly release date of this DEV branch // RR = release increments - 00 in DEV branches // .XX = incremental changes