mirror of
https://github.com/moodle/moodle.git
synced 2025-08-04 16:36:37 +02:00
MDL-27520 core_grades: accept feedback files via grade_update()
This commit is contained in:
parent
3cced42eb3
commit
5d7a9ea6f9
5 changed files with 158 additions and 4 deletions
|
@ -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.
|
* GRADE_MIN_MAX_FROM_GRADE_GRADE - Get the grade min/max from the grade grade.
|
||||||
*/
|
*/
|
||||||
define('GRADE_MIN_MAX_FROM_GRADE_GRADE', 2);
|
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');
|
||||||
|
|
|
@ -172,6 +172,22 @@ class grade_grade extends grade_object {
|
||||||
*/
|
*/
|
||||||
public $aggregationweight = null;
|
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
|
* 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
|
* @return int The new grade_grade ID if successful, false otherwise
|
||||||
*/
|
*/
|
||||||
public function insert($source=null) {
|
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)
|
// TODO: dategraded hack - do not update times, they are used for submission and grading (MDL-31379)
|
||||||
//$this->timecreated = $this->timemodified = time();
|
//$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
|
* @return bool success
|
||||||
*/
|
*/
|
||||||
public function update($source=null) {
|
public function update($source=null) {
|
||||||
|
global $USER, $CFG, $DB;
|
||||||
|
|
||||||
$this->rawgrade = grade_floatval($this->rawgrade);
|
$this->rawgrade = grade_floatval($this->rawgrade);
|
||||||
$this->finalgrade = grade_floatval($this->finalgrade);
|
$this->finalgrade = grade_floatval($this->finalgrade);
|
||||||
$this->rawgrademin = grade_floatval($this->rawgrademin);
|
$this->rawgrademin = grade_floatval($this->rawgrademin);
|
||||||
$this->rawgrademax = grade_floatval($this->rawgrademax);
|
$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(),
|
return array('status' => $this->get_aggregationstatus(),
|
||||||
'weight' => $this->get_aggregationweight());
|
'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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 $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 int $datesubmitted A timestamp of when the student's work was submitted
|
||||||
* @param grade_grade $grade A grade object, useful for bulk upgrades
|
* @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
|
* @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;
|
global $USER;
|
||||||
|
|
||||||
$result = true;
|
$result = true;
|
||||||
|
@ -1929,6 +1939,7 @@ class grade_item extends grade_object {
|
||||||
if ($feedback !== false and !$grade->is_overridden()) {
|
if ($feedback !== false and !$grade->is_overridden()) {
|
||||||
$grade->feedback = $feedback;
|
$grade->feedback = $feedback;
|
||||||
$grade->feedbackformat = $feedbackformat;
|
$grade->feedbackformat = $feedbackformat;
|
||||||
|
$grade->feedbackfiles = $feedbackfiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update final grade if possible
|
// update final grade if possible
|
||||||
|
|
|
@ -252,6 +252,7 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
|
||||||
$rawgrade = false;
|
$rawgrade = false;
|
||||||
$feedback = false;
|
$feedback = false;
|
||||||
$feedbackformat = FORMAT_MOODLE;
|
$feedbackformat = FORMAT_MOODLE;
|
||||||
|
$feedbackfiles = [];
|
||||||
$usermodified = $USER->id;
|
$usermodified = $USER->id;
|
||||||
$datesubmitted = null;
|
$datesubmitted = null;
|
||||||
$dategraded = null;
|
$dategraded = null;
|
||||||
|
@ -268,6 +269,10 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
|
||||||
$feedbackformat = $grade['feedbackformat'];
|
$feedbackformat = $grade['feedbackformat'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('feedbackfiles', $grade)) {
|
||||||
|
$feedbackfiles = $grade['feedbackfiles'];
|
||||||
|
}
|
||||||
|
|
||||||
if (array_key_exists('usermodified', $grade)) {
|
if (array_key_exists('usermodified', $grade)) {
|
||||||
$usermodified = $grade['usermodified'];
|
$usermodified = $grade['usermodified'];
|
||||||
}
|
}
|
||||||
|
@ -281,7 +286,8 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
|
||||||
}
|
}
|
||||||
|
|
||||||
// update or insert the grade
|
// 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;
|
$failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,6 +135,16 @@ the groupid field.
|
||||||
- message_contact_unblocked
|
- message_contact_unblocked
|
||||||
The reason for this is because you can now block/unblock users without them necessarily being a contact. These events
|
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.
|
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 ===
|
=== 3.5 ===
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue