MDL-59250 mod_workshop: New WS mod_workshop_update_assessment

This commit is contained in:
Juan Leyva 2017-06-28 11:24:49 +01:00
parent 57f44fbac4
commit fe966a2720
4 changed files with 247 additions and 2 deletions

View File

@ -1412,4 +1412,132 @@ class mod_workshop_external extends external_api {
)
);
}
/**
* Returns the description of the external function parameters.
*
* @return external_function_parameters
* @since Moodle 3.4
*/
public static function update_assessment_parameters() {
return new external_function_parameters(
array(
'assessmentid' => new external_value(PARAM_INT, 'Assessment id.'),
'data' => new external_multiple_structure (
new external_single_structure(
array(
'name' => new external_value(PARAM_ALPHANUMEXT,
'The assessment data (use WS get_assessment_form_definition for obtaining the data to sent).
Apart from that data, you can optionally send:
feedbackauthor (str); the feedback for the submission author
feedbackauthorformat (int); the format of the feedbackauthor
feedbackauthorinlineattachmentsid (int); the draft file area for the editor attachments
feedbackauthorattachmentsid (int); the draft file area id for the feedback attachments'
),
'value' => new external_value(PARAM_RAW, 'The value of the option.')
)
), 'Assessment data'
)
)
);
}
/**
* Updates an assessment.
*
* @param int $assessmentid the assessment id
* @param array $data the assessment data
* @return array indicates if the assessment was updated, the new raw grade and possible warnings.
* @since Moodle 3.4
* @throws moodle_exception
*/
public static function update_assessment($assessmentid, $data) {
global $DB, $USER;
$params = self::validate_parameters(
self::update_assessment_parameters(), array('assessmentid' => $assessmentid, 'data' => $data)
);
$warnings = array();
// Get and validate the assessment, submission and workshop.
$assessment = $DB->get_record('workshop_assessments', array('id' => $params['assessmentid']), '*', MUST_EXIST);
$submission = $DB->get_record('workshop_submissions', array('id' => $assessment->submissionid), '*', MUST_EXIST);
list($workshop, $course, $cm, $context) = self::validate_workshop($submission->workshopid);
// Check we can edit the assessment.
$workshop->check_edit_assessment($assessment, $submission);
// Process data.
$data = new stdClass;
$data->feedbackauthor_editor = array();
foreach ($params['data'] as $wsdata) {
$name = trim($wsdata['name']);
switch ($name) {
case 'feedbackauthor':
$data->feedbackauthor_editor['text'] = $wsdata['value'];
break;
case 'feedbackauthorformat':
$data->feedbackauthor_editor['format'] = clean_param($wsdata['value'], PARAM_FORMAT);
break;
case 'feedbackauthorinlineattachmentsid':
$data->feedbackauthor_editor['itemid'] = clean_param($wsdata['value'], PARAM_INT);
break;
case 'feedbackauthorattachmentsid':
$data->feedbackauthorattachment_filemanager = clean_param($wsdata['value'], PARAM_INT);
break;
default:
$data->{$wsdata['name']} = $wsdata['value']; // Validation will be done in the form->validation.
}
}
$cansetassessmentweight = has_capability('mod/workshop:allocate', $context);
$pending = $workshop->get_pending_assessments_by_reviewer($assessment->reviewerid, $assessment->id);
// Retrieve the data from the strategy plugin.
$strategy = $workshop->grading_strategy_instance();
$mform = $strategy->get_assessment_form(null, 'assessment', $assessment, true,
array('editableweight' => $cansetassessmentweight, 'pending' => !empty($pending)));
$errors = $mform->validation((array) $data, array());
// We can get several errors, return them in warnings.
if (!empty($errors)) {
$status = false;
$rawgrade = null;
foreach ($errors as $itemname => $message) {
$warnings[] = array(
'item' => $itemname,
'itemid' => 0,
'warningcode' => 'fielderror',
'message' => s($message)
);
}
} else {
$rawgrade = $workshop->edit_assessment($assessment, $submission, $data, $strategy);
$status = true;
}
return array(
'status' => $status,
'rawgrade' => $rawgrade,
'warnings' => $warnings,
);
}
/**
* Returns description of method result value
*
* @return external_description
* @since Moodle 3.4
*/
public static function update_assessment_returns() {
return new external_single_structure(
array(
'status' => new external_value(PARAM_BOOL, 'status: true if the assessment was added or updated false otherwise.'),
'rawgrade' => new external_value(PARAM_FLOAT, 'Raw percentual grade (0.00000 to 100.00000) for submission.',
VALUE_OPTIONAL),
'warnings' => new external_warnings()
)
);
}
}

View File

@ -127,4 +127,11 @@ $functions = array(
'type' => 'read',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
),
'mod_workshop_update_assessment' => array(
'classname' => 'mod_workshop_external',
'methodname' => 'update_assessment',
'description' => 'Add information to an allocated assessment.',
'type' => 'write',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
),
);

View File

@ -75,7 +75,12 @@ class mod_workshop_external_testcase extends externallib_advanced_testcase {
$course->groupmode = SEPARATEGROUPS;
$course->groupmodeforce = true;
$this->course = $this->getDataGenerator()->create_course($course);
$this->workshop = $this->getDataGenerator()->create_module('workshop', array('course' => $this->course->id));
$this->workshop = $this->getDataGenerator()->create_module('workshop',
array(
'course' => $this->course->id,
'overallfeedbackfiles' => 1,
)
);
$this->context = context_module::instance($this->workshop->cmid);
$this->cm = get_coursemodule_from_instance('workshop', $this->workshop->id);
@ -1414,4 +1419,109 @@ class mod_workshop_external_testcase extends externallib_advanced_testcase {
$this->setExpectedException('moodle_exception');
mod_workshop_external::get_reviewer_assessments($this->workshop->id, $this->anotherstudentg1->id);
}
/**
* Test update_assessment.
*/
public function test_update_assessment() {
global $DB;
// Create the submission.
$submissionid = $this->create_test_submission($this->anotherstudentg1);
$workshop = new workshop($this->workshop, $this->cm, $this->course);
$submission = $workshop->get_submission_by_id($submissionid);
$assessmentid = $workshop->add_allocation($submission, $this->student->id);
// Switch to assessment phase.
$DB->set_field('workshop', 'phase', workshop::PHASE_ASSESSMENT, array('id' => $this->workshop->id));
$this->setUser($this->student);
// Get the form definition.
$result = mod_workshop_external::get_assessment_form_definition($assessmentid);
$result = external_api::clean_returnvalue(mod_workshop_external::get_assessment_form_definition_returns(), $result);
// Prepare the data to be sent.
$data = $result['fields'];
foreach ($data as $key => $param) {
if (strpos($param['name'], 'peercomment__idx_') === 0) {
$data[$key]['value'] = 'Some content';
} else if (strpos($param['name'], 'grade__idx_') === 0) {
$data[$key]['value'] = 25; // Set all to 25.
}
}
// Required data.
$data[] = array(
'name' => 'nodims',
'value' => $result['dimenssionscount'],
);
// General feedback.
$data[] = array(
'name' => 'feedbackauthor',
'value' => 'Feedback for the author',
);
$data[] = array(
'name' => 'feedbackauthorformat',
'value' => FORMAT_MOODLE,
);
// Create a file in a draft area for inline attachments.
$fs = get_file_storage();
$draftidinlineattach = file_get_unused_draft_itemid();
$usercontext = context_user::instance($this->student->id);
$filenameimg = 'shouldbeanimage.txt';
$filerecordinline = array(
'contextid' => $usercontext->id,
'component' => 'user',
'filearea' => 'draft',
'itemid' => $draftidinlineattach,
'filepath' => '/',
'filename' => $filenameimg,
);
$fs->create_file_from_string($filerecordinline, 'image contents (not really)');
// Create a file in a draft area for regular attachments.
$draftidattach = file_get_unused_draft_itemid();
$filerecordattach = $filerecordinline;
$attachfilename = 'attachment.txt';
$filerecordattach['filename'] = $attachfilename;
$filerecordattach['itemid'] = $draftidattach;
$fs->create_file_from_string($filerecordattach, 'simple text attachment');
$data[] = array(
'name' => 'feedbackauthorinlineattachmentsid',
'value' => $draftidinlineattach,
);
$data[] = array(
'name' => 'feedbackauthorattachmentsid',
'value' => $draftidattach,
);
// Update the assessment.
$result = mod_workshop_external::update_assessment($assessmentid, $data);
$result = external_api::clean_returnvalue(mod_workshop_external::update_assessment_returns(), $result);
$this->assertEquals(100, $result['rawgrade']);
$this->assertTrue($result['status']);
// Get the assessment and check it was updated properly.
$result = mod_workshop_external::get_assessment($assessmentid);
$result = external_api::clean_returnvalue(mod_workshop_external::get_assessment_returns(), $result);
$this->assertEquals(100, $result['assessment']['grade']);
$this->assertEquals($this->student->id, $result['assessment']['reviewerid']);
$this->assertEquals('Feedback for the author', $result['assessment']['feedbackauthor']);
$this->assertCount(1, $result['assessment']['feedbackcontentfiles']);
$this->assertCount(1, $result['assessment']['feedbackattachmentfiles']);
// Now, get again the form and check we received the data we already sent.
$result = mod_workshop_external::get_assessment_form_definition($assessmentid);
$result = external_api::clean_returnvalue(mod_workshop_external::get_assessment_form_definition_returns(), $result);
foreach ($result['current'] as $currentdata) {
if (strpos($currentdata['name'], 'peercomment__idx_') === 0) {
$this->assertEquals('Some content', $currentdata['value']);
} else if (strpos($currentdata['name'], 'grade__idx_') === 0) {
$this->assertEquals(25, (int) $currentdata['value']);
}
}
}
}

View File

@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051513; // The current module version (YYYYMMDDXX)
$plugin->version = 2017051514; // The current module version (YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->component = 'mod_workshop';
$plugin->cron = 60; // Give as a chance every minute.