MDL-21572 Gradebook: Do not export fields when missing permissions

This commit is contained in:
Frederic Massart 2012-07-10 14:51:57 +08:00
parent 293f42b67a
commit 61c8e0d75f
13 changed files with 199 additions and 73 deletions

View File

@ -60,7 +60,7 @@ if (has_capability('moodle/grade:manage', $systemcontext)
$temp->add(new admin_setting_configtext('grade_export_userprofilefields', new lang_string('gradeexportuserprofilefields', 'grades'), new lang_string('gradeexportuserprofilefields_desc', 'grades'), 'firstname,lastname,idnumber,institution,department,email', PARAM_TEXT));
$temp->add(new admin_setting_configtext('grade_export_customprofilefields', new lang_string('gradeexportcustomprofilefields', 'grades'), new lang_string('gradeexportcustomprofilefields_desc', 'grades'), null));
$temp->add(new admin_setting_configtext('grade_export_customprofilefields', new lang_string('gradeexportcustomprofilefields', 'grades'), new lang_string('gradeexportcustomprofilefields_desc', 'grades'), null, PARAM_TEXT));
$temp->add(new admin_setting_configcheckbox('recovergradesdefault', new lang_string('recovergradesdefault', 'grades'), new lang_string('recovergradesdefault_help', 'grades'), 0));

View File

@ -40,6 +40,8 @@ abstract class grade_export {
public $displaytype; // display type (e.g. real, percentages, letter) for exports
public $decimalpoints; // number of decimal points for exports
public $onlyactive; // only include users with an active enrolment
public $usercustomfields; // include users custom fields
/**
* Constructor should set up all the private variables ready to be pulled
* @access public
@ -47,10 +49,14 @@ abstract class grade_export {
* @param int $groupid id of selected group, 0 means all
* @param string $itemlist comma separated list of item ids, empty means all
* @param boolean $export_feedback
* @param boolean $export_letters
* @param boolean $updatedgradesonly
* @param string $displaytype
* @param int $decimalpoints
* @param boolean $onlyactive
* @param boolean $usercustomfields include user custom field in export
* @note Exporting as letters will lead to data loss if that exported set it re-imported.
*/
public function grade_export($course, $groupid=0, $itemlist='', $export_feedback=false, $updatedgradesonly = false, $displaytype = GRADE_DISPLAY_TYPE_REAL, $decimalpoints = 2, $onlyactive = false) {
public function grade_export($course, $groupid=0, $itemlist='', $export_feedback=false, $updatedgradesonly = false, $displaytype = GRADE_DISPLAY_TYPE_REAL, $decimalpoints = 2, $onlyactive = false, $usercustomfields = false) {
$this->course = $course;
$this->groupid = $groupid;
$this->grade_items = grade_item::fetch_all(array('courseid'=>$this->course->id));
@ -85,6 +91,7 @@ abstract class grade_export {
$this->displaytype = $displaytype;
$this->decimalpoints = $decimalpoints;
$this->onlyactive = $onlyactive;
$this->usercustomfields = $usercustomfields;
}
/**
@ -205,11 +212,16 @@ abstract class grade_export {
*/
public function display_preview($require_user_idnumber=false) {
global $OUTPUT;
$userprofilefields = grade_helper::get_user_profile_fields($this->course->id, $this->usercustomfields);
$formatoptions = new stdClass();
$formatoptions->para = false;
echo $OUTPUT->heading(get_string('previewrows', 'grades'));
echo '<table>';
echo '<tr>';
foreach (get_user_profile_fields() as $field) {
foreach ($userprofilefields as $field) {
echo '<th>' . $field->fullname . '</th>';
}
foreach ($this->columns as $grade_item) {
@ -222,10 +234,10 @@ abstract class grade_export {
}
echo '</tr>';
/// Print all the lines of data.
$i = 0;
$gui = new graded_users_iterator($this->course, $this->columns, $this->groupid);
$gui->require_active_enrolment($this->onlyactive);
$gui->allow_user_custom_fields($this->usercustomfields);
$gui->init();
while ($userdata = $gui->next_user()) {
// number of preview rows
@ -266,8 +278,10 @@ abstract class grade_export {
}
echo '<tr>';
foreach (get_user_profile_fields() as $field) {
echo '<td>' . $user->{$field->shortname} . '</td>';
foreach ($userprofilefields as $field) {
$fieldvalue = grade_helper::get_user_field_value($user, $field);
// @see profile_field_base::display_data().
echo '<td>' . format_text($fieldvalue, FORMAT_MOODLE, $formatoptions) . '</td>';
}
echo $rowstr;
echo "</tr>";
@ -297,7 +311,8 @@ abstract class grade_export {
'updatedgradesonly' =>$this->updatedgradesonly,
'displaytype' =>$this->displaytype,
'decimalpoints' =>$this->decimalpoints,
'export_onlyactive' =>$this->onlyactive);
'export_onlyactive' =>$this->onlyactive,
'usercustomfields' =>$this->usercustomfields);
return $params;
}

View File

@ -45,7 +45,7 @@ if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('
}
// print all the exported data here
$export = new grade_export_ods($course, $groupid, $itemids, $export_feedback, $updatedgradesonly, $displaytype, $decimalpoints, $onlyactive);
$export = new grade_export_ods($course, $groupid, $itemids, $export_feedback, $updatedgradesonly, $displaytype, $decimalpoints, $onlyactive, true);
$export->print_grades();

View File

@ -43,16 +43,17 @@ class grade_export_ods extends grade_export {
// Adding the worksheet
$myxls =& $workbook->add_worksheet($strgrades);
// Print names of all the fields
$profilefields = get_user_profile_fields();
// Print names of all the fields.
$profilefields = grade_helper::get_user_profile_fields($this->course->id, $this->usercustomfields);
foreach ($profilefields as $id => $field) {
$myxls->write_string(0,$id,$field->fullname);
$myxls->write_string(0, $id, $field->fullname);
}
$pos = count($profilefields);
foreach ($this->columns as $grade_item) {
$myxls->write_string(0, $pos++, $this->format_column_name($grade_item));
/// add a column_feedback column
// Add a column_feedback column.
if ($this->export_feedback) {
$myxls->write_string(0, $pos++, $this->format_column_name($grade_item, true));
}
@ -63,15 +64,17 @@ class grade_export_ods extends grade_export {
$geub = new grade_export_update_buffer();
$gui = new graded_users_iterator($this->course, $this->columns, $this->groupid);
$gui->require_active_enrolment($this->onlyactive);
$gui->allow_user_custom_fields($this->usercustomfields);
$gui->init();
while ($userdata = $gui->next_user()) {
$i++;
$user = $userdata->user;
foreach($profilefields as $id => $field) {
$myxls->write_string($i,$id,$user->{$field->shortname});
$fieldvalue = grade_helper::get_user_field_value($user, $field);
$myxls->write_string($i, $id, $fieldvalue);
}
$j=count($profilefields);
$j = count($profilefields);
foreach ($userdata->grades as $itemid => $grade) {
if ($export_tracking) {
@ -95,7 +98,7 @@ class grade_export_ods extends grade_export {
$gui->close();
$geub->close();
// Close the workbook
// Close the workbook.
$workbook->close();
exit;

View File

@ -51,7 +51,7 @@ if ($groupmode == SEPARATEGROUPS and !$currentgroup and !has_capability('moodle/
// process post information
if ($data = $mform->get_data()) {
$export = new grade_export_ods($course, $currentgroup, '', false, false, $data->display, $data->decimals, $data->export_onlyactive);
$export = new grade_export_ods($course, $currentgroup, '', false, false, $data->display, $data->decimals, $data->export_onlyactive, true);
// print the grades on screen for feedbacks
$export->process_form($data);

View File

@ -46,7 +46,7 @@ if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('
}
// print all the exported data here
$export = new grade_export_txt($course, $groupid, $itemids, $export_feedback, $updatedgradesonly, $displaytype, $decimalpoints, $separator, $onlyactive);
$export = new grade_export_txt($course, $groupid, $itemids, $export_feedback, $updatedgradesonly, $displaytype, $decimalpoints, $separator, $onlyactive, true);
$export->print_grades();

View File

@ -23,8 +23,20 @@ class grade_export_txt extends grade_export {
public $separator; // default separator
public function __construct($course, $groupid=0, $itemlist='', $export_feedback=false, $updatedgradesonly = false, $displaytype = GRADE_DISPLAY_TYPE_REAL, $decimalpoints = 2, $separator = 'comma', $onlyactive = false) {
parent::__construct($course, $groupid, $itemlist, $export_feedback, $updatedgradesonly, $displaytype, $decimalpoints, $onlyactive);
/**
* Constructor should set up all the private variables ready to be pulled
* @param object $course
* @param int $groupid id of selected group, 0 means all
* @param string $itemlist comma separated list of item ids, empty means all
* @param boolean $export_feedback
* @param boolean $updatedgradesonly
* @param string $displaytype
* @param int $decimalpoints
* @param boolean $onlyactive
* @param boolean $usercustomfields include user custom field in export
*/
public function __construct($course, $groupid=0, $itemlist='', $export_feedback=false, $updatedgradesonly = false, $displaytype = GRADE_DISPLAY_TYPE_REAL, $decimalpoints = 2, $separator = 'comma', $onlyactive = false, $usercustomfields = false) {
parent::__construct($course, $groupid, $itemlist, $export_feedback, $updatedgradesonly, $displaytype, $decimalpoints, $onlyactive, $usercustomfields);
$this->separator = $separator;
}
@ -40,7 +52,7 @@ class grade_export_txt extends grade_export {
$export_tracking = $this->track_exports();
$strgrades = get_string('grades');
$profilefields = get_user_profile_fields();
$profilefields = grade_helper::get_user_profile_fields($this->course->id, $this->usercustomfields);
switch ($this->separator) {
case 'comma':
@ -76,17 +88,18 @@ class grade_export_txt extends grade_export {
foreach ($this->columns as $grade_item) {
echo $separator.$this->format_column_name($grade_item);
// Add a feedback column
// Add a feedback column.
if ($this->export_feedback) {
echo $separator.$this->format_column_name($grade_item, true);
}
}
echo "\n";
/// Print all the lines of data.
// Print all the lines of data.
$geub = new grade_export_update_buffer();
$gui = new graded_users_iterator($this->course, $this->columns, $this->groupid);
$gui->require_active_enrolment($this->onlyactive);
$gui->allow_user_custom_fields($this->usercustomfields);
$gui->init();
while ($userdata = $gui->next_user()) {
@ -94,7 +107,8 @@ class grade_export_txt extends grade_export {
$items = array();
foreach ($profilefields as $field) {
$items[] = $user->{$field->shortname};
$fieldvalue = grade_helper::get_user_field_value($user, $field);
$items[] = $fieldvalue;
}
echo implode($separator, $items);

View File

@ -51,7 +51,7 @@ if ($groupmode == SEPARATEGROUPS and !$currentgroup and !has_capability('moodle/
// process post information
if ($data = $mform->get_data()) {
$export = new grade_export_txt($course, $currentgroup, '', false, false, $data->display, $data->decimals, $data->separator, $data->export_onlyactive);
$export = new grade_export_txt($course, $currentgroup, '', false, false, $data->display, $data->decimals, $data->separator, $data->export_onlyactive, true);
// print the grades on screen for feedback

View File

@ -45,7 +45,7 @@ if (groups_get_course_groupmode($COURSE) == SEPARATEGROUPS and !has_capability('
}
// print all the exported data here
$export = new grade_export_xls($course, $groupid, $itemids, $export_feedback, $updatedgradesonly, $displaytype, $decimalpoints, $onlyactive);
$export = new grade_export_xls($course, $groupid, $itemids, $export_feedback, $updatedgradesonly, $displaytype, $decimalpoints, $onlyactive, true);
$export->print_grades();

View File

@ -43,11 +43,11 @@ class grade_export_xls extends grade_export {
$myxls =& $workbook->add_worksheet($strgrades);
// Print names of all the fields
$profilefields = get_user_profile_fields();
$profilefields = grade_helper::get_user_profile_fields($this->course->id, $this->usercustomfields);
foreach ($profilefields as $id => $field) {
$myxls->write_string(0,$id,$field->fullname);
$myxls->write_string(0, $id, $field->fullname);
}
$pos=count($profilefields);
$pos = count($profilefields);
foreach ($this->columns as $grade_item) {
$myxls->write_string(0, $pos++, $this->format_column_name($grade_item));
@ -63,15 +63,17 @@ class grade_export_xls extends grade_export {
$geub = new grade_export_update_buffer();
$gui = new graded_users_iterator($this->course, $this->columns, $this->groupid);
$gui->require_active_enrolment($this->onlyactive);
$gui->allow_user_custom_fields($this->usercustomfields);
$gui->init();
while ($userdata = $gui->next_user()) {
$i++;
$user = $userdata->user;
foreach ($profilefields as $id => $field) {
$myxls->write_string($i,$id,$user->{$field->shortname});
$fieldvalue = grade_helper::get_user_field_value($user, $field);
$myxls->write_string($i, $id, $fieldvalue);
}
$j=count($profilefields);
$j = count($profilefields);
foreach ($userdata->grades as $itemid => $grade) {
if ($export_tracking) {

View File

@ -51,7 +51,7 @@ if ($groupmode == SEPARATEGROUPS and !$currentgroup and !has_capability('moodle/
// process post information
if ($data = $mform->get_data()) {
$export = new grade_export_xls($course, $currentgroup, '', false, false, $data->display, $data->decimals, $data->export_onlyactive);
$export = new grade_export_xls($course, $currentgroup, '', false, false, $data->display, $data->decimals, $data->export_onlyactive, true);
// print the grades on screen for feedbacks
$export->process_form($data);

View File

@ -88,6 +88,11 @@ class graded_users_iterator {
*/
protected $onlyactive = false;
/**
* Enable user custom fields
*/
protected $allowusercustomfields = false;
/**
* Constructor
*
@ -171,15 +176,18 @@ class graded_users_iterator {
$userfields = 'u.*';
$customfieldssql = '';
if ($CFG->grade_export_customprofilefields) {
$customfieldcount = 0;
foreach (get_user_profile_fields() as $field) {
if ($field->customid) {
if ($this->allowusercustomfields && !empty($CFG->grade_export_customprofilefields)) {
$customfieldscount = 0;
$customfieldsarray = grade_helper::get_user_profile_fields($this->course->id, $this->allowusercustomfields);
foreach ($customfieldsarray as $field) {
if (!empty($field->customid)) {
$customfieldssql .= "
LEFT JOIN (SELECT * FROM {user_info_data} WHERE fieldid=$field->customid) cf$customfieldcount
ON u.id = cf$customfieldcount.userid";
$userfields .= ", cf$customfieldcount.data AS $field->shortname";
$customfieldcount++;
LEFT JOIN (SELECT * FROM {user_info_data}
WHERE fieldid = :cf$customfieldscount) cf$customfieldscount
ON u.id = cf$customfieldscount.userid";
$userfields .= ", cf$customfieldscount.data AS 'customfield_{$field->shortname}'";
$params['cf'.$customfieldscount] = $field->customid;
$customfieldscount++;
}
}
}
@ -326,6 +334,19 @@ class graded_users_iterator {
$this->onlyactive = $onlyactive;
}
/**
* Allow custom fields to be included
*
* @param bool $allow Whether to allow custom fields or not
* @return void
*/
public function allow_user_custom_fields($allow = true) {
if ($allow) {
$this->allowusercustomfields = true;
} else {
$this->allowusercustomfields = false;
}
}
/**
* Add a grade_grade instance to the grade stack
@ -2680,40 +2701,101 @@ abstract class grade_helper {
}
return self::$exportplugins;
}
}
/**
* Returns an array of user profile fields to be included in export
*
* @return array An array of stdClass instances with customid, shortname and fullname fields
*/
function get_user_profile_fields() {
global $CFG, $DB;
$fields = array();
$userprofilefields = explode(",", $CFG->grade_export_userprofilefields);
if ($userprofilefields) {
foreach ($userprofilefields as $field) {
$obj = new stdClass();
$obj->customid = 0;
$obj->shortname = $field;
$obj->fullname = get_string($field);
$fields[] = $obj;
/**
* Returns the value of a field from a user record
*
* @param stdClass $user object
* @param stdClass $field object
* @return string value of the field
*/
public static function get_user_field_value($user, $field) {
if (!empty($field->customid)) {
$fieldname = 'customfield_' . $field->shortname;
if (!empty($user->{$fieldname}) || is_numeric($user->{$fieldname})) {
$fieldvalue = $user->{$fieldname};
} else {
$fieldvalue = $field->default;
}
} else {
$fieldvalue = $user->{$field->shortname};
}
return $fieldvalue;
}
$customprofilefields = explode(",", $CFG->grade_export_customprofilefields);
if (isset($customprofilefields)) {
foreach ($customprofilefields as $field) {
$record = $DB->get_record('user_info_field', array('shortname' => $field));
if ($record) {
/**
* Returns an array of user profile fields to be included in export
*
* @param int $courseid
* @param bool $includecustomfields
* @return array An array of stdClass instances with customid, shortname, datatype, default and fullname fields
*/
public static function get_user_profile_fields($courseid, $includecustomfields = false) {
global $CFG, $DB;
// Gets the fields that have to be hidden
$hiddenfields = array_map('trim', explode(',', $CFG->hiddenuserfields));
$context = context_course::instance($courseid);
$canseehiddenfields = has_capability('moodle/course:viewhiddenuserfields', $context);
if ($canseehiddenfields) {
$hiddenfields = array();
}
$fields = array();
require_once($CFG->dirroot.'/user/lib.php'); // Loads user_get_default_fields()
require_once($CFG->dirroot.'/user/profile/lib.php'); // Loads constants, such as PROFILE_VISIBLE_ALL
$userdefaultfields = user_get_default_fields();
// Sets the list of profile fields
$userprofilefields = array_map('trim', explode(',', $CFG->grade_export_userprofilefields));
if (!empty($userprofilefields)) {
foreach ($userprofilefields as $field) {
$field = trim($field);
if (in_array($field, $hiddenfields) || !in_array($field, $userdefaultfields)) {
continue;
}
$obj = new stdClass();
$obj->customid = $record->id;
$obj->customid = 0;
$obj->shortname = $field;
$obj->fullname = $record->name;
$obj->fullname = get_string($field);
$fields[] = $obj;
}
}
}
return $fields;
// Sets the list of custom profile fields
$customprofilefields = array_map('trim', explode(',', $CFG->grade_export_customprofilefields));
if ($includecustomfields && !empty($customprofilefields)) {
list($wherefields, $whereparams) = $DB->get_in_or_equal($customprofilefields);
$customfields = $DB->get_records_sql("SELECT f.*
FROM {user_info_field} f
JOIN {user_info_category} c ON f.categoryid=c.id
WHERE f.shortname $wherefields
ORDER BY c.sortorder ASC, f.sortorder ASC", $whereparams);
if (!is_array($customfields)) {
continue;
}
foreach ($customfields as $field) {
// Make sure we can display this custom field
if (!in_array($field->shortname, $customprofilefields)) {
continue;
} else if (in_array($field->shortname, $hiddenfields)) {
continue;
} else if ($field->visible != PROFILE_VISIBLE_ALL && !$canseehiddenfields) {
continue;
}
$obj = new stdClass();
$obj->customid = $field->id;
$obj->shortname = $field->shortname;
$obj->fullname = format_string($field->name);
$obj->datatype = $field->datatype;
$obj->default = $field->defaultdata;
$fields[] = $obj;
}
}
return $fields;
}
}

View File

@ -166,6 +166,22 @@ function user_get_users_by_id($userids) {
return $DB->get_records_list('user', 'id', $userids);
}
/**
* Returns the list of default 'displayable' fields
*
* Contains database field names but also names used to generate information, such as enrolledcourses
*
* @return array of user fields
*/
function user_get_default_fields() {
return array( 'id', 'username', 'fullname', 'firstname', 'lastname', 'email',
'address', 'phone1', 'phone2', 'icq', 'skype', 'yahoo', 'aim', 'msn', 'department',
'institution', 'interests', 'firstaccess', 'lastaccess', 'auth', 'confirmed',
'idnumber', 'lang', 'theme', 'timezone', 'mailformat', 'description', 'descriptionformat',
'city', 'url', 'country', 'profileimageurlsmall', 'profileimageurl', 'customfields',
'groups', 'roles', 'preferences', 'enrolledcourses'
);
}
/**
*
@ -186,13 +202,7 @@ function user_get_user_details($user, $course = null, array $userfields = array(
require_once($CFG->dirroot . "/user/profile/lib.php"); //custom field library
require_once($CFG->dirroot . "/lib/filelib.php"); // file handling on description and friends
$defaultfields = array( 'id', 'username', 'fullname', 'firstname', 'lastname', 'email',
'address', 'phone1', 'phone2', 'icq', 'skype', 'yahoo', 'aim', 'msn', 'department',
'institution', 'interests', 'firstaccess', 'lastaccess', 'auth', 'confirmed',
'idnumber', 'lang', 'theme', 'timezone', 'mailformat', 'description', 'descriptionformat',
'city', 'url', 'country', 'profileimageurlsmall', 'profileimageurl', 'customfields',
'groups', 'roles', 'preferences', 'enrolledcourses'
);
$defaultfields = user_get_default_fields();
if (empty($userfields)) {
$userfields = $defaultfields;