MDL-27520 core_grades: accept feedback files via grade_update()

This commit is contained in:
Mark Nelson 2018-09-14 11:37:10 +08:00
parent 3cced42eb3
commit 5d7a9ea6f9
5 changed files with 158 additions and 4 deletions

View File

@ -263,3 +263,13 @@ define('GRADE_MIN_MAX_FROM_GRADE_ITEM', 1);
* GRADE_MIN_MAX_FROM_GRADE_GRADE - Get the grade min/max from the grade grade.
*/
define('GRADE_MIN_MAX_FROM_GRADE_GRADE', 2);
/**
* The component to store grade files.
*/
define('GRADE_FILE_COMPONENT', 'grade');
/**
* The file area to store grade feedback files.
*/
define('GRADE_FEEDBACK_FILEAREA', 'feedback');

View File

@ -172,6 +172,22 @@ class grade_grade extends grade_object {
*/
public $aggregationweight = null;
/**
* Feedback files to copy.
*
* Example -
*
* [
* 'contextid' => 1,
* 'component' => 'mod_xyz',
* 'filearea' => 'mod_xyz_feedback',
* 'itemid' => 2
* ];
*
* @var array
*/
public $feedbackfiles = [];
/**
* Returns array of grades for given grade_item+users
*
@ -1004,9 +1020,45 @@ class grade_grade extends grade_object {
* @return int The new grade_grade ID if successful, false otherwise
*/
public function insert($source=null) {
global $USER, $CFG, $DB;
// TODO: dategraded hack - do not update times, they are used for submission and grading (MDL-31379)
//$this->timecreated = $this->timemodified = time();
return parent::insert($source);
if (!empty($this->id)) {
debugging("Grade object already exists!");
return false;
}
$data = $this->get_record_data();
$this->id = $DB->insert_record($this->table, $data);
// Set all object properties from real db data.
$this->update_from_db();
$data = $this->get_record_data();
if (empty($CFG->disablegradehistory)) {
unset($data->timecreated);
$data->action = GRADE_HISTORY_INSERT;
$data->oldid = $this->id;
$data->source = $source;
$data->timemodified = time();
$data->loggeduser = $USER->id;
$DB->insert_record($this->table.'_history', $data);
}
$this->notify_changed(false);
// We only support feedback files for modules atm.
if ($this->grade_item && $this->grade_item->is_external_item()) {
$cm = get_coursemodule_from_instance($this->grade_item->itemmodule, $this->grade_item->iteminstance,
0, false, MUST_EXIST);
$modulecontext = context_module::instance($cm->id);
$this->copy_feedback_files($modulecontext, $this->id);
}
return $this->id;
}
/**
@ -1017,11 +1069,47 @@ class grade_grade extends grade_object {
* @return bool success
*/
public function update($source=null) {
global $USER, $CFG, $DB;
$this->rawgrade = grade_floatval($this->rawgrade);
$this->finalgrade = grade_floatval($this->finalgrade);
$this->rawgrademin = grade_floatval($this->rawgrademin);
$this->rawgrademax = grade_floatval($this->rawgrademax);
return parent::update($source);
if (empty($this->id)) {
debugging('Can not update grade object, no id!');
return false;
}
$data = $this->get_record_data();
$DB->update_record($this->table, $data);
if (empty($CFG->disablegradehistory)) {
unset($data->timecreated);
$data->action = GRADE_HISTORY_UPDATE;
$data->oldid = $this->id;
$data->source = $source;
$data->timemodified = time();
$data->loggeduser = $USER->id;
$DB->insert_record($this->table.'_history', $data);
}
$this->notify_changed(false);
// We only support feedback files for modules atm.
if ($this->grade_item && $this->grade_item->is_external_item()) {
$cm = get_coursemodule_from_instance($this->grade_item->itemmodule, $this->grade_item->iteminstance,
0, false, MUST_EXIST);
$modulecontext = context_module::instance($cm->id);
$fs = new file_storage();
$fs->delete_area_files($modulecontext->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA, $this->id);
$this->copy_feedback_files($modulecontext, $this->id);
}
return true;
}
/**
@ -1121,4 +1209,33 @@ class grade_grade extends grade_object {
return array('status' => $this->get_aggregationstatus(),
'weight' => $this->get_aggregationweight());
}
/**
* Handles copying feedback files to the gradebook feedback area.
*
* @param context $context
* @param int $itemid
*/
private function copy_feedback_files(context $context, int $itemid) {
if ($this->feedbackfiles) {
$filestocopycontextid = $this->feedbackfiles['contextid'];
$filestocopycomponent = $this->feedbackfiles['component'];
$filestocopyfilearea = $this->feedbackfiles['filearea'];
$filestocopyitemid = $this->feedbackfiles['itemid'];
$fs = new file_storage();
if ($filestocopy = $fs->get_area_files($filestocopycontextid, $filestocopycomponent, $filestocopyfilearea,
$filestocopyitemid)) {
foreach ($filestocopy as $filetocopy) {
$destination = [
'contextid' => $context->id,
'component' => GRADE_FILE_COMPONENT,
'filearea' => GRADE_FEEDBACK_FILEAREA,
'itemid' => $itemid
];
$fs->create_file_from_storedfile($destination, $filetocopy);
}
}
}
}
}

View File

@ -1864,9 +1864,19 @@ class grade_item extends grade_object {
* @param int $dategraded A timestamp of when the student's work was graded
* @param int $datesubmitted A timestamp of when the student's work was submitted
* @param grade_grade $grade A grade object, useful for bulk upgrades
* @param array $feedbackfiles An array identifying the location of files we want to copy to the gradebook feedback area.
* Example -
* [
* 'contextid' => 1,
* 'component' => 'mod_xyz',
* 'filearea' => 'mod_xyz_feedback',
* 'itemid' => 2
* ];
* @return bool success
*/
public function update_raw_grade($userid, $rawgrade=false, $source=NULL, $feedback=false, $feedbackformat=FORMAT_MOODLE, $usermodified=null, $dategraded=null, $datesubmitted=null, $grade=null) {
public function update_raw_grade($userid, $rawgrade = false, $source = null, $feedback = false,
$feedbackformat = FORMAT_MOODLE, $usermodified = null, $dategraded = null, $datesubmitted=null,
$grade = null, array $feedbackfiles = []) {
global $USER;
$result = true;
@ -1929,6 +1939,7 @@ class grade_item extends grade_object {
if ($feedback !== false and !$grade->is_overridden()) {
$grade->feedback = $feedback;
$grade->feedbackformat = $feedbackformat;
$grade->feedbackfiles = $feedbackfiles;
}
// update final grade if possible

View File

@ -252,6 +252,7 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
$rawgrade = false;
$feedback = false;
$feedbackformat = FORMAT_MOODLE;
$feedbackfiles = [];
$usermodified = $USER->id;
$datesubmitted = null;
$dategraded = null;
@ -268,6 +269,10 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
$feedbackformat = $grade['feedbackformat'];
}
if (array_key_exists('feedbackfiles', $grade)) {
$feedbackfiles = $grade['feedbackfiles'];
}
if (array_key_exists('usermodified', $grade)) {
$usermodified = $grade['usermodified'];
}
@ -281,7 +286,8 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
}
// update or insert the grade
if (!$grade_item->update_raw_grade($userid, $rawgrade, $source, $feedback, $feedbackformat, $usermodified, $dategraded, $datesubmitted, $grade_grade)) {
if (!$grade_item->update_raw_grade($userid, $rawgrade, $source, $feedback, $feedbackformat, $usermodified,
$dategraded, $datesubmitted, $grade_grade, $feedbackfiles)) {
$failed = true;
}
}

View File

@ -135,6 +135,16 @@ the groupid field.
- message_contact_unblocked
The reason for this is because you can now block/unblock users without them necessarily being a contact. These events
have been replaced with message_user_blocked and message_user_unblocked respectively.
* The gradebook now supports the ability to accept files as feedback. This can be achieved by adding
'feedbackfiles' to the $grades parameter passed to grade_update().
For example -
$grades['feedbackfiles'] = [
'contextid' => 1,
'component' => 'mod_xyz',
'filearea' => 'mod_xyz_feedback',
'itemid' => 2
];
These files will be then copied to the gradebook file area.
=== 3.5 ===