MDL-37148 Assignment: Lots more webservices
This patch adds lots of webservices to the assignment module. * mod_assign_revert_submissions_to_draft * mod_assign_lock_submissions * mod_assign_unlock_submissions * mod_assign_save_submission * mod_assign_submit_for_grading * mod_assign_save_grade * mod_assign_save_user_extensions * mod_assign_reveal_identities * mod_assign_copy_previous_attempt All features such as reopening attempts and marking workflow are supported through the save_grade and save_submission functions. Uploading files is supported by sending draft item ids for the files_filemanager param the same functions.
This commit is contained in:
@@ -627,5 +627,13 @@ abstract class assign_plugin {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If this plugin can participate in a webservice (save_submission or save_grade),
|
||||
* return a list of external_params to be included in the definition of that webservice.
|
||||
*
|
||||
* @return external_description|null
|
||||
*/
|
||||
public function get_external_parameters() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,5 +63,70 @@ $functions = array(
|
||||
'classpath' => 'mod/assign/externallib.php',
|
||||
'description' => 'Returns the blind marking mappings for assignments',
|
||||
'type' => 'read'
|
||||
),
|
||||
|
||||
'mod_assign_revert_submissions_to_draft' => array(
|
||||
'classname' => 'mod_assign_external',
|
||||
'methodname' => 'revert_submissions_to_draft',
|
||||
'classpath' => 'mod/assign/externallib.php',
|
||||
'description' => 'Reverts the list of submissions to draft status',
|
||||
'type' => 'write'
|
||||
),
|
||||
|
||||
'mod_assign_lock_submissions' => array(
|
||||
'classname' => 'mod_assign_external',
|
||||
'methodname' => 'lock_submissions',
|
||||
'classpath' => 'mod/assign/externallib.php',
|
||||
'description' => 'Prevent students from making changes to a list of submissions',
|
||||
'type' => 'write'
|
||||
),
|
||||
|
||||
'mod_assign_unlock_submissions' => array(
|
||||
'classname' => 'mod_assign_external',
|
||||
'methodname' => 'unlock_submissions',
|
||||
'classpath' => 'mod/assign/externallib.php',
|
||||
'description' => 'Allow students to make changes to a list of submissions',
|
||||
'type' => 'write'
|
||||
),
|
||||
|
||||
'mod_assign_save_submission' => array(
|
||||
'classname' => 'mod_assign_external',
|
||||
'methodname' => 'save_submission',
|
||||
'classpath' => 'mod/assign/externallib.php',
|
||||
'description' => 'Update the current students submission',
|
||||
'type' => 'write'
|
||||
),
|
||||
|
||||
'mod_assign_submit_for_grading' => array(
|
||||
'classname' => 'mod_assign_external',
|
||||
'methodname' => 'submit_for_grading',
|
||||
'classpath' => 'mod/assign/externallib.php',
|
||||
'description' => 'Submit the current students assignment for grading',
|
||||
'type' => 'write'
|
||||
),
|
||||
|
||||
'mod_assign_save_grade' => array(
|
||||
'classname' => 'mod_assign_external',
|
||||
'methodname' => 'save_grade',
|
||||
'classpath' => 'mod/assign/externallib.php',
|
||||
'description' => 'Save a grade update for a single student.',
|
||||
'type' => 'write'
|
||||
),
|
||||
|
||||
'mod_assign_save_user_extensions' => array(
|
||||
'classname' => 'mod_assign_external',
|
||||
'methodname' => 'save_user_extensions',
|
||||
'classpath' => 'mod/assign/externallib.php',
|
||||
'description' => 'Save a list of assignment extensions',
|
||||
'type' => 'write'
|
||||
),
|
||||
|
||||
'mod_assign_reveal_identities' => array(
|
||||
'classname' => 'mod_assign_external',
|
||||
'methodname' => 'reveal_identities',
|
||||
'classpath' => 'mod/assign/externallib.php',
|
||||
'description' => 'Reveal the identities for a blind marking assignment',
|
||||
'type' => 'write'
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
+633
-2
@@ -32,6 +32,38 @@ require_once("$CFG->libdir/externallib.php");
|
||||
*/
|
||||
class mod_assign_external extends external_api {
|
||||
|
||||
/**
|
||||
* Generate a warning in a standard structure for a known failure.
|
||||
*
|
||||
* @param int $assignmentid - The assignment
|
||||
* @param string $warningcode - The key for the warning message (@see $warningmessages)
|
||||
* @param string $detail - A description of the error
|
||||
* @return array - Warning structure containing item, itemid, warningcode, message
|
||||
*/
|
||||
private static function generate_warning($assignmentid, $warningcode, $detail) {
|
||||
$warningmessages = array(
|
||||
'couldnotlock'=>'Could not lock the submission for this user.',
|
||||
'couldnotunlock'=>'Could not unlock the submission for this user.',
|
||||
'couldnotsubmitforgrading'=>'Could not submit assignment for grading.',
|
||||
'couldnotrevealidentities'=>'Could not reveal identities.',
|
||||
'couldnotgrantextensions'=>'Could not grant submission date extensions.',
|
||||
'couldnotrevert'=>'Could not revert submission to draft.',
|
||||
'invalidparameters'=>'Invalid parameters.',
|
||||
'couldnotsavesubmission'=>'Could not save submission.',
|
||||
'couldnotsavegrade'=>'Could not save grade.'
|
||||
);
|
||||
|
||||
$message = $warningmessages[$warningcode];
|
||||
if (empty($message)) {
|
||||
$message = 'Unknown warning type.';
|
||||
}
|
||||
|
||||
return array('item'=>$detail,
|
||||
'itemid'=>$assignmentid,
|
||||
'warningcode'=>$warningcode,
|
||||
'message'=>$message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the parameters for get_grades
|
||||
* @return external_external_function_parameters
|
||||
@@ -102,7 +134,7 @@ class mod_assign_external extends external_api {
|
||||
WHERE mxg.assignment ' . $inorequalsql2 . ' GROUP BY mxg.userid';
|
||||
|
||||
$sql = "SELECT ag.id,ag.assignment,ag.userid,ag.timecreated,ag.timemodified,".
|
||||
"ag.grader,ag.grade ".
|
||||
"ag.grader,ag.grade,ag.attemptnumber ".
|
||||
"FROM {assign_grades} ag ".
|
||||
"JOIN ( " . $grademaxattempt . " ) gmx ON ag.userid = gmx.userid".
|
||||
" WHERE ag.assignment ".$inorequalsql.
|
||||
@@ -122,6 +154,7 @@ class mod_assign_external extends external_api {
|
||||
$grade['timecreated'] = $rd->timecreated;
|
||||
$grade['timemodified'] = $rd->timemodified;
|
||||
$grade['grader'] = $rd->grader;
|
||||
$grade['attemptnumber'] = $rd->attemptnumber;
|
||||
$grade['grade'] = (string)$rd->grade;
|
||||
|
||||
if (is_null($currentassignmentid) || ($rd->assignment != $currentassignmentid )) {
|
||||
@@ -170,6 +203,7 @@ class mod_assign_external extends external_api {
|
||||
array(
|
||||
'id' => new external_value(PARAM_INT, 'grade id'),
|
||||
'userid' => new external_value(PARAM_INT, 'student id'),
|
||||
'attemptnumber' => new external_value(PARAM_INT, 'attempt number'),
|
||||
'timecreated' => new external_value(PARAM_INT, 'grade creation time'),
|
||||
'timemodified' => new external_value(PARAM_INT, 'grade last modified time'),
|
||||
'grader' => new external_value(PARAM_INT, 'grader'),
|
||||
@@ -528,7 +562,7 @@ class mod_assign_external extends external_api {
|
||||
WHERE mxs.assignment = :assignid1 GROUP BY mxs.userid';
|
||||
|
||||
$sql = "SELECT mas.id, mas.assignment,mas.userid,".
|
||||
"mas.timecreated,mas.timemodified,mas.status,mas.groupid ".
|
||||
"mas.timecreated,mas.timemodified,mas.status,mas.groupid,mas.attemptnumber ".
|
||||
"FROM {assign_submission} mas ".
|
||||
"JOIN ( " . $submissionmaxattempt . " ) smx ON mas.userid = smx.userid ".
|
||||
"WHERE mas.assignment = :assignid2 AND mas.attemptnumber = smx.maxattempt";
|
||||
@@ -557,6 +591,7 @@ class mod_assign_external extends external_api {
|
||||
'timecreated' => $submissionrecord->timecreated,
|
||||
'timemodified' => $submissionrecord->timemodified,
|
||||
'status' => $submissionrecord->status,
|
||||
'attemptnumber' => $submissionrecord->attemptnumber,
|
||||
'groupid' => $submissionrecord->groupid
|
||||
);
|
||||
foreach ($submissionplugins as $submissionplugin) {
|
||||
@@ -638,6 +673,7 @@ class mod_assign_external extends external_api {
|
||||
array(
|
||||
'id' => new external_value(PARAM_INT, 'submission id'),
|
||||
'userid' => new external_value(PARAM_INT, 'student id'),
|
||||
'attemptnumber' => new external_value(PARAM_INT, 'attempt number'),
|
||||
'timecreated' => new external_value(PARAM_INT, 'submission creation time'),
|
||||
'timemodified' => new external_value(PARAM_INT, 'submission last modified time'),
|
||||
'status' => new external_value(PARAM_TEXT, 'submission status'),
|
||||
@@ -995,4 +1031,599 @@ class mod_assign_external extends external_api {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the parameters for lock_submissions
|
||||
* @return external_external_function_parameters
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function lock_submissions_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'),
|
||||
'userids' => new external_multiple_structure(
|
||||
new external_value(PARAM_INT, 'user id'),
|
||||
'1 or more user ids',
|
||||
VALUE_REQUIRED),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks (prevent updates to) submissions in this assignment.
|
||||
*
|
||||
* @param int $assignmentid The id of the assignment
|
||||
* @param array $userids Array of user ids to lock
|
||||
* @return array of warnings for each submission that could not be locked.
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function lock_submissions($assignmentid, $userids) {
|
||||
global $CFG;
|
||||
require_once("$CFG->dirroot/mod/assign/locallib.php");
|
||||
|
||||
$params = self::validate_parameters(self::lock_submissions_parameters(),
|
||||
array('assignmentid' => $assignmentid,
|
||||
'userids' => $userids));
|
||||
|
||||
$cm = get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assignment = new assign($context, $cm, null);
|
||||
|
||||
$warnings = array();
|
||||
foreach ($userids as $userid) {
|
||||
if (!$assignment->lock_submission($userid)) {
|
||||
$detail = 'User id: ' . $userid . ', Assignment id: ' . $assignmentid;
|
||||
$warnings[] = self::generate_warning($assignmentid,
|
||||
'couldnotlock',
|
||||
$detail);
|
||||
}
|
||||
}
|
||||
|
||||
return $warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the return value for lock_submissions
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function lock_submissions_returns() {
|
||||
return new external_multiple_structure(
|
||||
new external_warnings()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the parameters for revert_submissions_to_draft
|
||||
* @return external_external_function_parameters
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function revert_submissions_to_draft_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'),
|
||||
'userids' => new external_multiple_structure(
|
||||
new external_value(PARAM_INT, 'user id'),
|
||||
'1 or more user ids',
|
||||
VALUE_REQUIRED),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverts a list of user submissions to draft for a single assignment.
|
||||
*
|
||||
* @param int $assignmentid The id of the assignment
|
||||
* @param array $userids Array of user ids to revert
|
||||
* @return array of warnings for each submission that could not be reverted.
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function revert_submissions_to_draft($assignmentid, $userids) {
|
||||
global $CFG;
|
||||
require_once("$CFG->dirroot/mod/assign/locallib.php");
|
||||
|
||||
$params = self::validate_parameters(self::revert_submissions_to_draft_parameters(),
|
||||
array('assignmentid' => $assignmentid,
|
||||
'userids' => $userids));
|
||||
|
||||
$cm = get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assignment = new assign($context, $cm, null);
|
||||
|
||||
$warnings = array();
|
||||
foreach ($userids as $userid) {
|
||||
if (!$assignment->revert_to_draft($userid)) {
|
||||
$detail = 'User id: ' . $userid . ', Assignment id: ' . $assignmentid;
|
||||
$warnings[] = self::generate_warning($assignmentid,
|
||||
'couldnotrevert',
|
||||
$detail);
|
||||
}
|
||||
}
|
||||
|
||||
return $warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the return value for revert_submissions_to_draft
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function revert_submissions_to_draft_returns() {
|
||||
return new external_multiple_structure(
|
||||
new external_warnings()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the parameters for unlock_submissions
|
||||
* @return external_external_function_parameters
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function unlock_submissions_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'),
|
||||
'userids' => new external_multiple_structure(
|
||||
new external_value(PARAM_INT, 'user id'),
|
||||
'1 or more user ids',
|
||||
VALUE_REQUIRED),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks (prevent updates to) submissions in this assignment.
|
||||
*
|
||||
* @param int $assignmentid The id of the assignment
|
||||
* @param array $userids Array of user ids to lock
|
||||
* @return array of warnings for each submission that could not be locked.
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function unlock_submissions($assignmentid, $userids) {
|
||||
global $CFG;
|
||||
require_once("$CFG->dirroot/mod/assign/locallib.php");
|
||||
|
||||
$params = self::validate_parameters(self::unlock_submissions_parameters(),
|
||||
array('assignmentid' => $assignmentid,
|
||||
'userids' => $userids));
|
||||
|
||||
$cm = get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assignment = new assign($context, $cm, null);
|
||||
|
||||
$warnings = array();
|
||||
foreach ($userids as $userid) {
|
||||
if (!$assignment->unlock_submission($userid)) {
|
||||
$detail = 'User id: ' . $userid . ', Assignment id: ' . $assignmentid;
|
||||
$warnings[] = self::generate_warning($assignmentid,
|
||||
'couldnotunlock',
|
||||
$detail);
|
||||
}
|
||||
}
|
||||
|
||||
return $warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the return value for unlock_submissions
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function unlock_submissions_returns() {
|
||||
return new external_multiple_structure(
|
||||
new external_warnings()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the parameters for unlock_submissions
|
||||
* @return external_external_function_parameters
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function submit_for_grading_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit the logged in users assignment for grading.
|
||||
*
|
||||
* @param int $assignmentid The id of the assignment
|
||||
* @return array of warnings to indicate any errors.
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function submit_for_grading($assignmentid) {
|
||||
global $CFG, $USER;
|
||||
require_once("$CFG->dirroot/mod/assign/locallib.php");
|
||||
|
||||
$params = self::validate_parameters(self::submit_for_grading_parameters(),
|
||||
array('assignmentid' => $assignmentid));
|
||||
|
||||
$cm = get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assignment = new assign($context, $cm, null);
|
||||
|
||||
$warnings = array();
|
||||
if (!$assignment->submit_for_grading()) {
|
||||
$detail = 'User id: ' . $USER->id . ', Assignment id: ' . $assignmentid;
|
||||
$warnings[] = self::generate_warning($assignmentid,
|
||||
'couldnotsubmitforgrading',
|
||||
$detail);
|
||||
}
|
||||
|
||||
return $warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the return value for submit_for_grading
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function submit_for_grading_returns() {
|
||||
return new external_multiple_structure(
|
||||
new external_warnings()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the parameters for save_user_extensions
|
||||
* @return external_external_function_parameters
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function save_user_extensions_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'),
|
||||
'userids' => new external_multiple_structure(
|
||||
new external_value(PARAM_INT, 'user id'),
|
||||
'1 or more user ids',
|
||||
VALUE_REQUIRED),
|
||||
'dates' => new external_multiple_structure(
|
||||
new external_value(PARAM_INT, 'dates'),
|
||||
'1 or more extension dates (timestamp)',
|
||||
VALUE_REQUIRED),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grant extension dates to students for an assignment.
|
||||
*
|
||||
* @param int $assignmentid The id of the assignment
|
||||
* @param array $userids Array of user ids to grant extensions to
|
||||
* @param array $dates Array of extension dates
|
||||
* @return array of warnings for each extension date that could not be granted
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function save_user_extensions($assignmentid, $userids, $dates) {
|
||||
global $CFG;
|
||||
require_once("$CFG->dirroot/mod/assign/locallib.php");
|
||||
|
||||
$params = self::validate_parameters(self::save_user_extensions_parameters(),
|
||||
array('assignmentid' => $assignmentid,
|
||||
'userids' => $userids,
|
||||
'dates' => $dates));
|
||||
|
||||
if (count($userids) != count($dates)) {
|
||||
$detail = 'Length of userids and dates parameters differ.';
|
||||
$warnings[] = self::generate_warning($assignmentid,
|
||||
'invalidparameters',
|
||||
$detail);
|
||||
|
||||
return $warnings;
|
||||
}
|
||||
|
||||
$cm = get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assignment = new assign($context, $cm, null);
|
||||
|
||||
$warnings = array();
|
||||
foreach ($userids as $idx => $userid) {
|
||||
$duedate = $dates[$idx];
|
||||
if (!$assignment->save_user_extension($userid, $duedate)) {
|
||||
$detail = 'User id: ' . $userid . ', Assignment id: ' . $assignmentid . ', Extension date: ' . $duedate;
|
||||
$warnings[] = self::generate_warning($assignmentid,
|
||||
'couldnotgrantextensions',
|
||||
$detail);
|
||||
}
|
||||
}
|
||||
|
||||
return $warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the return value for save_user_extensions
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function save_user_extensions_returns() {
|
||||
return new external_multiple_structure(
|
||||
new external_warnings()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the parameters for reveal_identities
|
||||
* @return external_external_function_parameters
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function reveal_identities_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reveal the identities of anonymous students to markers for a single assignment.
|
||||
*
|
||||
* @param int $assignmentid The id of the assignment
|
||||
* @return array of warnings to indicate any errors.
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function reveal_identities($assignmentid) {
|
||||
global $CFG, $USER;
|
||||
require_once("$CFG->dirroot/mod/assign/locallib.php");
|
||||
|
||||
$params = self::validate_parameters(self::reveal_identities_parameters(),
|
||||
array('assignmentid' => $assignmentid));
|
||||
|
||||
$cm = get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assignment = new assign($context, $cm, null);
|
||||
|
||||
$warnings = array();
|
||||
if (!$assignment->reveal_identities()) {
|
||||
$detail = 'User id: ' . $USER->id . ', Assignment id: ' . $assignmentid;
|
||||
$warnings[] = self::generate_warning($assignmentid,
|
||||
'couldnotrevealidentities',
|
||||
$detail);
|
||||
}
|
||||
|
||||
return $warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the return value for reveal_identities
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function reveal_identities_returns() {
|
||||
return new external_multiple_structure(
|
||||
new external_warnings()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the parameters for save_submission
|
||||
* @return external_external_function_parameters
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function save_submission_parameters() {
|
||||
global $CFG;
|
||||
require_once("$CFG->dirroot/mod/assign/locallib.php");
|
||||
$instance = new assign(null, null, null);
|
||||
$pluginsubmissionparams = array();
|
||||
|
||||
foreach ($instance->get_submission_plugins() as $plugin) {
|
||||
$pluginparams = $plugin->get_external_parameters();
|
||||
if (!empty($pluginparams)) {
|
||||
$pluginsubmissionparams = array_merge($pluginsubmissionparams, $pluginparams);
|
||||
}
|
||||
}
|
||||
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'),
|
||||
'plugindata' => new external_single_structure(
|
||||
$pluginsubmissionparams
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a student submission for a single assignment.
|
||||
*
|
||||
* @param int $assignmentid The id of the assignment
|
||||
* @return array of warnings to indicate any errors.
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function save_submission($assignmentid, $plugindata) {
|
||||
global $CFG, $USER;
|
||||
require_once("$CFG->dirroot/mod/assign/locallib.php");
|
||||
|
||||
$params = self::validate_parameters(self::save_submission_parameters(),
|
||||
array('assignmentid' => $assignmentid,
|
||||
'plugindata' => $plugindata));
|
||||
|
||||
$cm = get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assignment = new assign($context, $cm, null);
|
||||
|
||||
$notices = array();
|
||||
|
||||
$submissiondata = (object)$plugindata;
|
||||
|
||||
$assignment->save_submission($submissiondata, $notices);
|
||||
|
||||
$warnings = array();
|
||||
foreach ($notices as $notice) {
|
||||
$warnings[] = self::generate_warning($assignmentid,
|
||||
'couldnotsavesubmission',
|
||||
$notice);
|
||||
}
|
||||
|
||||
return $warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the return value for save_submission
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function save_submission_returns() {
|
||||
return new external_multiple_structure(
|
||||
new external_warnings()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the parameters for save_grade
|
||||
* @return external_external_function_parameters
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function save_grade_parameters() {
|
||||
global $CFG;
|
||||
require_once("$CFG->dirroot/mod/assign/locallib.php");
|
||||
$instance = new assign(null, null, null);
|
||||
$pluginfeedbackparams = array();
|
||||
|
||||
foreach ($instance->get_feedback_plugins() as $plugin) {
|
||||
$pluginparams = $plugin->get_external_parameters();
|
||||
if (!empty($pluginparams)) {
|
||||
$pluginfeedbackparams = array_merge($pluginfeedbackparams, $pluginparams);
|
||||
}
|
||||
}
|
||||
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'),
|
||||
'userid' => new external_value(PARAM_INT, 'The student id to operate on'),
|
||||
'grade' => new external_value(PARAM_FLOAT, 'The new grade for this user'),
|
||||
'attemptnumber' => new external_value(PARAM_INT, 'The attempt number (-1 means latest attempt)'),
|
||||
'addattempt' => new external_value(PARAM_BOOL, 'Allow another attempt if the attempt reopen method is manual'),
|
||||
'workflowstate' => new external_value(PARAM_ALPHA, 'The next marking workflow state'),
|
||||
'applytoall' => new external_value(PARAM_BOOL, 'If true, this grade will be applied ' .
|
||||
'to all members ' .
|
||||
'of the group (for group assignments).'),
|
||||
'plugindata' => new external_single_structure(
|
||||
$pluginfeedbackparams
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a student grade for a single assignment.
|
||||
*
|
||||
* @param int $assignmentid The id of the assignment
|
||||
* @return null
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function save_grade($assignmentid, $userid, $grade, $attemptnumber, $addattempt, $workflowstate, $applytoall, $plugindata) {
|
||||
global $CFG, $USER;
|
||||
require_once("$CFG->dirroot/mod/assign/locallib.php");
|
||||
|
||||
$params = self::validate_parameters(self::save_grade_parameters(),
|
||||
array('assignmentid' => $assignmentid,
|
||||
'userid' => $userid,
|
||||
'grade' => $grade,
|
||||
'attemptnumber' => $attemptnumber,
|
||||
'workflowstate' => $workflowstate,
|
||||
'addattempt' => $addattempt,
|
||||
'applytoall' => $applytoall,
|
||||
'plugindata' => $plugindata));
|
||||
|
||||
$cm = get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assignment = new assign($context, $cm, null);
|
||||
|
||||
$gradedata = (object)$plugindata;
|
||||
|
||||
$gradedata->addattempt = $addattempt;
|
||||
$gradedata->attemptnumber = $attemptnumber;
|
||||
$gradedata->workflowstate = $workflowstate;
|
||||
$gradedata->applytoall = $applytoall;
|
||||
$gradedata->grade = $grade;
|
||||
|
||||
$assignment->save_grade($userid, $gradedata);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the return value for save_grade
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function save_grade_returns() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the parameters for copy_previous_attempt
|
||||
* @return external_external_function_parameters
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function copy_previous_attempt_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a students previous attempt to a new attempt.
|
||||
*
|
||||
* @return array of warnings to indicate any errors.
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function copy_previous_attempt($assignmentid) {
|
||||
global $CFG, $USER;
|
||||
require_once("$CFG->dirroot/mod/assign/locallib.php");
|
||||
|
||||
$params = self::validate_parameters(self::copy_previous_attempt_parameters(),
|
||||
array('assignmentid' => $assignmentid));
|
||||
|
||||
$cm = get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assignment = new assign($context, $cm, null);
|
||||
|
||||
$notices = array();
|
||||
|
||||
$assignment->copy_previous_attempt($submissiondata, $notices);
|
||||
|
||||
$warnings = array();
|
||||
foreach ($notices as $notice) {
|
||||
$warnings[] = self::generate_warning($assignmentid,
|
||||
'couldnotcopyprevioussubmission',
|
||||
$notice);
|
||||
}
|
||||
|
||||
return $warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the return value for save_submission
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since Moodle 2.6
|
||||
*/
|
||||
public static function copy_previous_attempt_returns() {
|
||||
return new external_multiple_structure(
|
||||
new external_warnings()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -390,4 +390,16 @@ class assign_feedback_comments extends assign_feedback_plugin {
|
||||
return $this->view($grade) == '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a description of external params suitable for uploading an feedback comment from a webservice.
|
||||
*
|
||||
* @return external_description|null
|
||||
*/
|
||||
public function get_external_parameters() {
|
||||
$editorparams = array('text' => new external_value(PARAM_TEXT, 'The text for this feedback.'),
|
||||
'format' => new external_value(PARAM_INT, 'The format for this feedback'));
|
||||
$editorstructure = new external_single_structure($editorparams);
|
||||
return array('assignfeedbackcomments_editor' => $editorstructure);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -609,4 +609,14 @@ class assign_feedback_file extends assign_feedback_plugin {
|
||||
public function get_grading_actions() {
|
||||
return array('uploadzip'=>get_string('uploadzip', 'assignfeedback_file'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a description of external params suitable for uploading a feedback file from a webservice.
|
||||
*
|
||||
* @return external_description|null
|
||||
*/
|
||||
public function get_external_parameters() {
|
||||
return array('files_filemanager' => new external_value(PARAM_INT, 'The id of a draft area containing files for this feedback.'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+405
-260
@@ -389,7 +389,7 @@ class assign {
|
||||
$nextpageparams['action'] = 'editsubmission';
|
||||
}
|
||||
} else if ($action == 'lock') {
|
||||
$this->process_lock();
|
||||
$this->process_lock_submission();
|
||||
$action = 'redirect';
|
||||
$nextpageparams['action'] = 'grading';
|
||||
} else if ($action == 'addattempt') {
|
||||
@@ -401,7 +401,7 @@ class assign {
|
||||
$action = 'redirect';
|
||||
$nextpageparams['action'] = 'grading';
|
||||
} else if ($action == 'unlock') {
|
||||
$this->process_unlock();
|
||||
$this->process_unlock_submission();
|
||||
$action = 'redirect';
|
||||
$nextpageparams['action'] = 'grading';
|
||||
} else if ($action == 'setbatchmarkingworkflowstate') {
|
||||
@@ -3314,9 +3314,9 @@ class assign {
|
||||
|
||||
foreach ($userlist as $userid) {
|
||||
if ($data->operation == 'lock') {
|
||||
$this->process_lock($userid);
|
||||
$this->process_lock_submission($userid);
|
||||
} else if ($data->operation == 'unlock') {
|
||||
$this->process_unlock($userid);
|
||||
$this->process_unlock_submission($userid);
|
||||
} else if ($data->operation == 'reverttodraft') {
|
||||
$this->process_revert_to_draft($userid);
|
||||
} else if ($data->operation == 'addattempt') {
|
||||
@@ -4462,6 +4462,71 @@ class assign {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit a submission for grading.
|
||||
*
|
||||
* @return bool Return false if the submission was not submitted.
|
||||
*/
|
||||
public function submit_for_grading() {
|
||||
global $USER;
|
||||
|
||||
// Need submit permission to submit an assignment.
|
||||
require_capability('mod/assign:submit', $this->context);
|
||||
|
||||
$instance = $this->get_instance();
|
||||
|
||||
if ($instance->teamsubmission) {
|
||||
$submission = $this->get_group_submission($USER->id, 0, true);
|
||||
} else {
|
||||
$submission = $this->get_user_submission($USER->id, true);
|
||||
}
|
||||
|
||||
if (!$this->submissions_open($USER->id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($submission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) {
|
||||
// Give each submission plugin a chance to process the submission.
|
||||
$plugins = $this->get_submission_plugins();
|
||||
foreach ($plugins as $plugin) {
|
||||
if ($plugin->is_enabled() && $plugin->is_visible()) {
|
||||
$plugin->submit_for_grading($submission);
|
||||
}
|
||||
}
|
||||
|
||||
$submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
|
||||
$this->update_submission($submission, $USER->id, true, $instance->teamsubmission);
|
||||
$completion = new completion_info($this->get_course());
|
||||
if ($completion->is_enabled($this->get_course_module()) && $instance->completionsubmit) {
|
||||
$completion->update_state($this->get_course_module(), COMPLETION_COMPLETE, $USER->id);
|
||||
}
|
||||
|
||||
if (isset($data->submissionstatement)) {
|
||||
$logmessage = get_string('submissionstatementacceptedlog',
|
||||
'mod_assign',
|
||||
fullname($USER));
|
||||
$this->add_to_log('submission statement accepted', $logmessage);
|
||||
}
|
||||
$logdata = $this->add_to_log('submit for grading', $this->format_submission_for_log($submission), '', true);
|
||||
$this->notify_graders($submission);
|
||||
$this->notify_student_submission_receipt($submission);
|
||||
|
||||
// Trigger assessable_submitted event on submission.
|
||||
$params = array(
|
||||
'context' => context_module::instance($this->get_course_module()->id),
|
||||
'objectid' => $submission->id,
|
||||
'other' => array(
|
||||
'submission_editable' => false
|
||||
)
|
||||
);
|
||||
$event = \mod_assign\event\assessable_submitted::create($params);
|
||||
$event->set_legacy_logdata($logdata);
|
||||
$event->trigger();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assignment submission is processed before grading.
|
||||
*
|
||||
@@ -4472,8 +4537,6 @@ class assign {
|
||||
protected function process_submit_for_grading($mform) {
|
||||
global $USER, $CFG;
|
||||
|
||||
// Need submit permission to submit an assignment.
|
||||
require_capability('mod/assign:submit', $this->context);
|
||||
require_once($CFG->dirroot . '/mod/assign/submissionconfirmform.php');
|
||||
require_sesskey();
|
||||
|
||||
@@ -4503,57 +4566,7 @@ class assign {
|
||||
if ($mform->get_data() == false) {
|
||||
return false;
|
||||
}
|
||||
if ($instance->teamsubmission) {
|
||||
$submission = $this->get_group_submission($USER->id, 0, true);
|
||||
} else {
|
||||
$submission = $this->get_user_submission($USER->id, true);
|
||||
}
|
||||
|
||||
if ($submission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) {
|
||||
// Give each submission plugin a chance to process the submission.
|
||||
$plugins = $this->get_submission_plugins();
|
||||
foreach ($plugins as $plugin) {
|
||||
if ($plugin->is_enabled() && $plugin->is_visible()) {
|
||||
$plugin->submit_for_grading($submission);
|
||||
}
|
||||
}
|
||||
|
||||
$submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
|
||||
$this->update_submission($submission, $USER->id, true, $instance->teamsubmission);
|
||||
$completion = new completion_info($this->get_course());
|
||||
if ($completion->is_enabled($this->get_course_module()) && $instance->completionsubmit) {
|
||||
$completion->update_state($this->get_course_module(), COMPLETION_COMPLETE, $USER->id);
|
||||
}
|
||||
|
||||
if (isset($data->submissionstatement)) {
|
||||
$logmessage = get_string('submissionstatementacceptedlog',
|
||||
'mod_assign',
|
||||
fullname($USER));
|
||||
$addtolog = $this->add_to_log('submission statement accepted', $logmessage, '', true);
|
||||
$params = array(
|
||||
'context' => $this->context,
|
||||
'objectid' => $submission->id
|
||||
);
|
||||
$event = \mod_assign\event\statement_accepted::create($params);
|
||||
$event->set_legacy_logdata($addtolog);
|
||||
$event->trigger();
|
||||
}
|
||||
$logdata = $this->add_to_log('submit for grading', $this->format_submission_for_log($submission), '', true);
|
||||
$this->notify_graders($submission);
|
||||
$this->notify_student_submission_receipt($submission);
|
||||
|
||||
// Trigger assessable_submitted event on submission.
|
||||
$params = array(
|
||||
'context' => context_module::instance($this->get_course_module()->id),
|
||||
'objectid' => $submission->id,
|
||||
'other' => array(
|
||||
'submission_editable' => false
|
||||
)
|
||||
);
|
||||
$event = \mod_assign\event\assessable_submitted::create($params);
|
||||
$event->set_legacy_logdata($logdata);
|
||||
$event->trigger();
|
||||
}
|
||||
return $this->submit_for_grading();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -4565,9 +4578,30 @@ class assign {
|
||||
* @param mixed $extensionduedate Either an integer date or null
|
||||
* @return boolean
|
||||
*/
|
||||
protected function save_user_extension($userid, $extensionduedate) {
|
||||
public function save_user_extension($userid, $extensionduedate) {
|
||||
global $DB;
|
||||
|
||||
// Need submit permission to submit an assignment.
|
||||
require_capability('mod/assign:grantextension', $this->context);
|
||||
|
||||
if (!is_enrolled($this->get_course_context(), $userid)) {
|
||||
return false;
|
||||
}
|
||||
if (!has_capability('mod/assign:submit', $this->context, $userid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->get_instance()->duedate && $extensionduedate) {
|
||||
if ($this->get_instance()->duedate > $extensionduedate) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ($this->get_instance()->allowsubmissionsfromdate && $extensionduedate) {
|
||||
if ($this->get_instance()->allowsubmissionsfromdate > $extensionduedate) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$flags = $this->get_user_flags($userid, true);
|
||||
$flags->extensionduedate = $extensionduedate;
|
||||
|
||||
@@ -4599,9 +4633,6 @@ class assign {
|
||||
// Include extension form.
|
||||
require_once($CFG->dirroot . '/mod/assign/extensionform.php');
|
||||
|
||||
// Need submit permission to submit an assignment.
|
||||
require_capability('mod/assign:grantextension', $this->context);
|
||||
|
||||
$batchusers = optional_param('selectedusers', '', PARAM_SEQUENCE);
|
||||
$userid = 0;
|
||||
if (!$batchusers) {
|
||||
@@ -4834,11 +4865,12 @@ class assign {
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function process_reveal_identities() {
|
||||
global $DB, $CFG;
|
||||
public function reveal_identities() {
|
||||
global $DB;
|
||||
|
||||
require_capability('mod/assign:revealidentities', $this->context);
|
||||
if (!confirm_sesskey()) {
|
||||
|
||||
if ($this->get_instance()->revealidentities || empty($this->get_instance()->blindmarking)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4882,6 +4914,20 @@ class assign {
|
||||
$event->trigger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reveal student identities to markers (and the gradebook).
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function process_reveal_identities() {
|
||||
|
||||
if (!confirm_sesskey()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->reveal_identities();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save grading options.
|
||||
@@ -5009,15 +5055,30 @@ class assign {
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the current assignment submission from the last submitted attempt.
|
||||
* Require a valid sess key and then call copy_previous_attempt.
|
||||
*
|
||||
* @param array $notices Any error messages that should be shown
|
||||
* to the user at the top of the edit submission form.
|
||||
* @return bool
|
||||
*/
|
||||
protected function process_copy_previous_attempt(&$notices) {
|
||||
require_sesskey();
|
||||
|
||||
return copy_previous_attempt($notices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the current assignment submission from the last submitted attempt.
|
||||
*
|
||||
* @param array $notices Any error messages that should be shown
|
||||
* to the user at the top of the edit submission form.
|
||||
* @return bool
|
||||
*/
|
||||
public function copy_previous_attempt(&$notices) {
|
||||
global $USER, $CFG;
|
||||
|
||||
require_capability('mod/assign:submit', $this->context);
|
||||
|
||||
$instance = $this->get_instance();
|
||||
if ($instance->teamsubmission) {
|
||||
$submission = $this->get_group_submission($USER->id, 0, true);
|
||||
@@ -5127,6 +5188,108 @@ class assign {
|
||||
return $allempty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save assignment submission for the current user.
|
||||
*
|
||||
* @param stdClass $data
|
||||
* @param array $notices Any error messages that should be shown
|
||||
* to the user.
|
||||
* @return bool
|
||||
*/
|
||||
public function save_submission(stdClass $data, & $notices) {
|
||||
global $CFG, $USER;
|
||||
|
||||
require_capability('mod/assign:submit', $this->context);
|
||||
$instance = $this->get_instance();
|
||||
|
||||
if ($instance->teamsubmission) {
|
||||
$submission = $this->get_group_submission($USER->id, 0, true);
|
||||
} else {
|
||||
$submission = $this->get_user_submission($USER->id, true);
|
||||
}
|
||||
if ($instance->submissiondrafts) {
|
||||
$submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
|
||||
} else {
|
||||
$submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
|
||||
}
|
||||
|
||||
$flags = $this->get_user_flags($USER->id, false);
|
||||
|
||||
// Get the flags to check if it is locked.
|
||||
if ($flags && $flags->locked) {
|
||||
print_error('submissionslocked', 'assign');
|
||||
return true;
|
||||
}
|
||||
|
||||
$pluginerror = false;
|
||||
foreach ($this->submissionplugins as $plugin) {
|
||||
if ($plugin->is_enabled() && $plugin->is_visible()) {
|
||||
if (!$plugin->save($submission, $data)) {
|
||||
$notices[] = $plugin->get_error();
|
||||
$pluginerror = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$allempty = $this->submission_empty($submission);
|
||||
if ($pluginerror || $allempty) {
|
||||
if ($allempty) {
|
||||
$notices[] = get_string('submissionempty', 'mod_assign');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->update_submission($submission, $USER->id, true, $instance->teamsubmission);
|
||||
|
||||
// Logging.
|
||||
if (isset($data->submissionstatement)) {
|
||||
$logmessage = get_string('submissionstatementacceptedlog',
|
||||
'mod_assign',
|
||||
fullname($USER));
|
||||
$this->add_to_log('submission statement accepted', $logmessage);
|
||||
$addtolog = $this->add_to_log('submission statement accepted', $logmessage, '', true);
|
||||
$params = array(
|
||||
'context' => $this->context,
|
||||
'objectid' => $submission->id
|
||||
);
|
||||
$event = \mod_assign\event\statement_accepted::create($params);
|
||||
$event->set_legacy_logdata($addtolog);
|
||||
$event->trigger();
|
||||
}
|
||||
$addtolog = $this->add_to_log('submit', $this->format_submission_for_log($submission), '', true);
|
||||
$params = array(
|
||||
'context' => $this->context,
|
||||
'objectid' => $submission->id
|
||||
);
|
||||
$event = \mod_assign\event\submission_updated::create($params);
|
||||
$event->set_legacy_logdata($addtolog);
|
||||
$event->trigger();
|
||||
|
||||
$complete = COMPLETION_INCOMPLETE;
|
||||
if ($submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED) {
|
||||
$complete = COMPLETION_COMPLETE;
|
||||
}
|
||||
$completion = new completion_info($this->get_course());
|
||||
if ($completion->is_enabled($this->get_course_module()) && $instance->completionsubmit) {
|
||||
$completion->update_state($this->get_course_module(), $complete, $USER->id);
|
||||
}
|
||||
|
||||
if (!$instance->submissiondrafts) {
|
||||
$this->notify_student_submission_receipt($submission);
|
||||
$this->notify_graders($submission);
|
||||
// Trigger assessable_submitted event on submission.
|
||||
$params = array(
|
||||
'context' => context_module::instance($this->get_course_module()->id),
|
||||
'objectid' => $submission->id,
|
||||
'other' => array(
|
||||
'submission_editable' => true
|
||||
)
|
||||
);
|
||||
$event = \mod_assign\event\assessable_submitted::create($params);
|
||||
$event->trigger();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save assignment submission.
|
||||
*
|
||||
@@ -5136,13 +5299,12 @@ class assign {
|
||||
* @return bool
|
||||
*/
|
||||
protected function process_save_submission(&$mform, &$notices) {
|
||||
global $USER, $CFG;
|
||||
global $CFG;
|
||||
|
||||
// Include submission form.
|
||||
require_once($CFG->dirroot . '/mod/assign/submission_form.php');
|
||||
|
||||
// Need submit permission to submit an assignment.
|
||||
require_capability('mod/assign:submit', $this->context);
|
||||
require_sesskey();
|
||||
if (!$this->submissions_open()) {
|
||||
$notices[] = get_string('duedatereached', 'assign');
|
||||
@@ -5156,92 +5318,7 @@ class assign {
|
||||
return true;
|
||||
}
|
||||
if ($data = $mform->get_data()) {
|
||||
if ($instance->teamsubmission) {
|
||||
$submission = $this->get_group_submission($USER->id, 0, true);
|
||||
} else {
|
||||
$submission = $this->get_user_submission($USER->id, true);
|
||||
}
|
||||
if ($instance->submissiondrafts) {
|
||||
$submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
|
||||
} else {
|
||||
$submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
|
||||
}
|
||||
|
||||
$flags = $this->get_user_flags($USER->id, false);
|
||||
|
||||
// Get the flags to check if it is locked.
|
||||
if ($flags && $flags->locked) {
|
||||
print_error('submissionslocked', 'assign');
|
||||
return true;
|
||||
}
|
||||
|
||||
$pluginerror = false;
|
||||
foreach ($this->submissionplugins as $plugin) {
|
||||
if ($plugin->is_enabled() && $plugin->is_visible()) {
|
||||
if (!$plugin->save($submission, $data)) {
|
||||
$notices[] = $plugin->get_error();
|
||||
$pluginerror = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$allempty = $this->submission_empty($submission);
|
||||
if ($pluginerror || $allempty) {
|
||||
if ($allempty) {
|
||||
$notices[] = get_string('submissionempty', 'mod_assign');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->update_submission($submission, $USER->id, true, $instance->teamsubmission);
|
||||
|
||||
// Logging.
|
||||
if (isset($data->submissionstatement)) {
|
||||
$logmessage = get_string('submissionstatementacceptedlog',
|
||||
'mod_assign',
|
||||
fullname($USER));
|
||||
$addtolog = $this->add_to_log('submission statement accepted', $logmessage, '', true);
|
||||
$params = array(
|
||||
'context' => $this->context,
|
||||
'objectid' => $submission->id
|
||||
);
|
||||
$event = \mod_assign\event\statement_accepted::create($params);
|
||||
$event->set_legacy_logdata($addtolog);
|
||||
$event->trigger();
|
||||
}
|
||||
|
||||
$addtolog = $this->add_to_log('submit', $this->format_submission_for_log($submission), '', true);
|
||||
$params = array(
|
||||
'context' => $this->context,
|
||||
'objectid' => $submission->id
|
||||
);
|
||||
$event = \mod_assign\event\submission_updated::create($params);
|
||||
$event->set_legacy_logdata($addtolog);
|
||||
$event->trigger();
|
||||
|
||||
$complete = COMPLETION_INCOMPLETE;
|
||||
if ($submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED) {
|
||||
$complete = COMPLETION_COMPLETE;
|
||||
}
|
||||
$completion = new completion_info($this->get_course());
|
||||
if ($completion->is_enabled($this->get_course_module()) && $instance->completionsubmit) {
|
||||
$completion->update_state($this->get_course_module(), $complete, $USER->id);
|
||||
}
|
||||
|
||||
if (!$instance->submissiondrafts) {
|
||||
$this->notify_student_submission_receipt($submission);
|
||||
$this->notify_graders($submission);
|
||||
// Trigger assessable_submitted event on submission.
|
||||
$params = array(
|
||||
'context' => context_module::instance($this->get_course_module()->id),
|
||||
'objectid' => $submission->id,
|
||||
'other' => array(
|
||||
'submission_editable' => true
|
||||
)
|
||||
);
|
||||
$event = \mod_assign\event\assessable_submitted::create($params);
|
||||
$event->trigger();
|
||||
}
|
||||
return true;
|
||||
return $this->save_submission($data, $notices);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -5677,21 +5754,15 @@ class assign {
|
||||
|
||||
/**
|
||||
* Revert to draft.
|
||||
* Uses url parameter userid
|
||||
*
|
||||
* @param int $userid
|
||||
* @return void
|
||||
* @return boolean
|
||||
*/
|
||||
protected function process_revert_to_draft($userid = 0) {
|
||||
public function revert_to_draft($userid) {
|
||||
global $DB, $USER;
|
||||
|
||||
// Need grade permission.
|
||||
require_capability('mod/assign:grade', $this->context);
|
||||
require_sesskey();
|
||||
|
||||
if (!$userid) {
|
||||
$userid = required_param('userid', PARAM_INT);
|
||||
}
|
||||
|
||||
if ($this->get_instance()->teamsubmission) {
|
||||
$submission = $this->get_group_submission($userid, 0, false);
|
||||
@@ -5700,7 +5771,7 @@ class assign {
|
||||
}
|
||||
|
||||
if (!$submission) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
$submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
|
||||
$this->update_submission($submission, $userid, true, $this->get_instance()->teamsubmission);
|
||||
@@ -5739,39 +5810,51 @@ class assign {
|
||||
$event = \mod_assign\event\submission_status_updated::create($params);
|
||||
$event->set_legacy_logdata($addtolog);
|
||||
$event->trigger();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock the process.
|
||||
* Uses url parameter userid
|
||||
* Revert to draft.
|
||||
* Uses url parameter userid if userid not supplied as a parameter.
|
||||
*
|
||||
* @param int $userid
|
||||
* @return void
|
||||
* @return boolean
|
||||
*/
|
||||
protected function process_lock($userid = 0) {
|
||||
global $USER, $DB;
|
||||
|
||||
// Need grade permission.
|
||||
require_capability('mod/assign:grade', $this->context);
|
||||
protected function process_revert_to_draft($userid = 0) {
|
||||
require_sesskey();
|
||||
|
||||
if (!$userid) {
|
||||
$userid = required_param('userid', PARAM_INT);
|
||||
}
|
||||
|
||||
return $this->revert_to_draft($userid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent student updates to this submission
|
||||
*
|
||||
* @param int $userid
|
||||
* @return bool
|
||||
*/
|
||||
public function lock_submission($userid) {
|
||||
global $USER, $DB;
|
||||
// Need grade permission.
|
||||
require_capability('mod/assign:grade', $this->context);
|
||||
|
||||
// Give each submission plugin a chance to process the locking.
|
||||
$plugins = $this->get_submission_plugins();
|
||||
$submission = $this->get_user_submission($userid, false);
|
||||
foreach ($plugins as $plugin) {
|
||||
if ($plugin->is_enabled() && $plugin->is_visible()) {
|
||||
$plugin->lock($submission);
|
||||
}
|
||||
}
|
||||
|
||||
$flags = $this->get_user_flags($userid, true);
|
||||
$flags->locked = 1;
|
||||
$this->update_user_flags($flags);
|
||||
|
||||
foreach ($plugins as $plugin) {
|
||||
if ($plugin->is_enabled() && $plugin->is_visible()) {
|
||||
$plugin->lock($submission, $flags);
|
||||
}
|
||||
}
|
||||
|
||||
$user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
|
||||
|
||||
$logmessage = get_string('locksubmissionforstudent',
|
||||
@@ -5786,6 +5869,7 @@ class assign {
|
||||
$event = \mod_assign\event\submission_locked::create($params);
|
||||
$event->set_legacy_logdata($addtolog);
|
||||
$event->trigger();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -5896,34 +5980,50 @@ class assign {
|
||||
|
||||
|
||||
/**
|
||||
* Unlock the process.
|
||||
* Prevent student updates to this submission.
|
||||
* Uses url parameter userid.
|
||||
*
|
||||
* @param int $userid
|
||||
* @return void
|
||||
*/
|
||||
protected function process_unlock($userid = 0) {
|
||||
global $USER, $DB;
|
||||
protected function process_lock_submission($userid = 0) {
|
||||
|
||||
// Need grade permission.
|
||||
require_capability('mod/assign:grade', $this->context);
|
||||
require_sesskey();
|
||||
|
||||
if (!$userid) {
|
||||
$userid = required_param('userid', PARAM_INT);
|
||||
}
|
||||
|
||||
return $this->lock_submission($userid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock the student submission.
|
||||
*
|
||||
* @param int $userid
|
||||
* @return bool
|
||||
*/
|
||||
public function unlock_submission($userid) {
|
||||
global $USER, $DB;
|
||||
|
||||
// Need grade permission.
|
||||
require_capability('mod/assign:grade', $this->context);
|
||||
|
||||
// Give each submission plugin a chance to process the unlocking.
|
||||
$plugins = $this->get_submission_plugins();
|
||||
$submission = $this->get_user_submission($userid, false);
|
||||
foreach ($plugins as $plugin) {
|
||||
if ($plugin->is_enabled() && $plugin->is_visible()) {
|
||||
$plugin->unlock($submission);
|
||||
}
|
||||
}
|
||||
|
||||
$flags = $this->get_user_flags($userid, true);
|
||||
$flags->locked = 0;
|
||||
$this->update_user_flags($flags);
|
||||
|
||||
foreach ($plugins as $plugin) {
|
||||
if ($plugin->is_enabled() && $plugin->is_visible()) {
|
||||
$plugin->unlock($submission, $flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
|
||||
|
||||
$logmessage = get_string('unlocksubmissionforstudent',
|
||||
@@ -5938,6 +6038,25 @@ class assign {
|
||||
$event = \mod_assign\event\submission_unlocked::create($params);
|
||||
$event->set_legacy_logdata($addtolog);
|
||||
$event->trigger();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock the student submission.
|
||||
* Uses url parameter userid.
|
||||
*
|
||||
* @param int $userid
|
||||
* @return bool
|
||||
*/
|
||||
protected function process_unlock_submission($userid = 0) {
|
||||
|
||||
require_sesskey();
|
||||
|
||||
if (!$userid) {
|
||||
$userid = required_param('userid', PARAM_INT);
|
||||
}
|
||||
|
||||
return $this->unlock_submission($userid);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6051,6 +6170,93 @@ class assign {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save grade update.
|
||||
*
|
||||
* @param int $userid
|
||||
* @param stdClass $data
|
||||
* @param int $attemptnumber - -1 means latest attempt
|
||||
* @return bool - was the grade saved
|
||||
*/
|
||||
public function save_grade($userid, $data) {
|
||||
|
||||
// Need grade permission.
|
||||
require_capability('mod/assign:grade', $this->context);
|
||||
|
||||
$instance = $this->get_instance();
|
||||
$submission = null;
|
||||
if ($instance->teamsubmission) {
|
||||
$submission = $this->get_group_submission($userid, 0, false, $data->attemptnumber);
|
||||
} else {
|
||||
$submission = $this->get_user_submission($userid, false, $data->attemptnumber);
|
||||
}
|
||||
if ($instance->teamsubmission && $data->applytoall) {
|
||||
$groupid = 0;
|
||||
if ($this->get_submission_group($userid)) {
|
||||
$group = $this->get_submission_group($userid);
|
||||
if ($group) {
|
||||
$groupid = $group->id;
|
||||
}
|
||||
}
|
||||
$members = $this->get_submission_group_members($groupid, true);
|
||||
foreach ($members as $member) {
|
||||
// User may exist in multple groups (which should put them in the default group).
|
||||
$this->apply_grade_to_user($data, $member->id, $data->attemptnumber);
|
||||
$this->process_outcomes($member->id, $data);
|
||||
}
|
||||
} else {
|
||||
$this->apply_grade_to_user($data, $userid, $data->attemptnumber);
|
||||
|
||||
$this->process_outcomes($userid, $data);
|
||||
}
|
||||
$maxattemptsreached = !empty($submission) &&
|
||||
$submission->attemptnumber >= ($instance->maxattempts - 1) &&
|
||||
$instance->maxattempts != ASSIGN_UNLIMITED_ATTEMPTS;
|
||||
$shouldreopen = false;
|
||||
if ($instance->attemptreopenmethod == ASSIGN_ATTEMPT_REOPEN_METHOD_UNTILPASS) {
|
||||
// Check the gradetopass from the gradebook.
|
||||
$gradinginfo = grade_get_grades($this->get_course()->id,
|
||||
'mod',
|
||||
'assign',
|
||||
$instance->id,
|
||||
$userid);
|
||||
|
||||
// What do we do if the grade has not been added to the gradebook (e.g. blind marking)?
|
||||
$gradingitem = null;
|
||||
$gradebookgrade = null;
|
||||
if (isset($gradinginfo->items[0])) {
|
||||
$gradingitem = $gradinginfo->items[0];
|
||||
$gradebookgrade = $gradingitem->grades[$userid];
|
||||
}
|
||||
|
||||
if ($gradebookgrade) {
|
||||
// TODO: This code should call grade_grade->is_passed().
|
||||
$shouldreopen = true;
|
||||
if (is_null($gradebookgrade->grade)) {
|
||||
$shouldreopen = false;
|
||||
}
|
||||
if (empty($gradingitem->gradepass) || $gradingitem->gradepass == $gradingitem->grademin) {
|
||||
$shouldreopen = false;
|
||||
}
|
||||
if ($gradebookgrade->grade >= $gradingitem->gradepass) {
|
||||
$shouldreopen = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($instance->attemptreopenmethod == ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL &&
|
||||
!empty($data->addattempt)) {
|
||||
$shouldreopen = true;
|
||||
}
|
||||
// Never reopen if we are editing a previous attempt.
|
||||
if ($data->attemptnumber != -1) {
|
||||
$shouldreopen = false;
|
||||
}
|
||||
if ($shouldreopen && !$maxattemptsreached) {
|
||||
$this->add_attempt($userid);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save grade.
|
||||
*
|
||||
@@ -6062,8 +6268,6 @@ class assign {
|
||||
// Include grade form.
|
||||
require_once($CFG->dirroot . '/mod/assign/gradeform.php');
|
||||
|
||||
// Need submit permission to submit an assignment.
|
||||
require_capability('mod/assign:grade', $this->context);
|
||||
require_sesskey();
|
||||
|
||||
$instance = $this->get_instance();
|
||||
@@ -6102,80 +6306,10 @@ class assign {
|
||||
array('class'=>'gradeform'));
|
||||
|
||||
if ($formdata = $mform->get_data()) {
|
||||
$submission = null;
|
||||
if ($instance->teamsubmission) {
|
||||
$submission = $this->get_group_submission($userid, 0, false, $attemptnumber);
|
||||
} else {
|
||||
$submission = $this->get_user_submission($userid, false, $attemptnumber);
|
||||
}
|
||||
if ($instance->teamsubmission && $formdata->applytoall) {
|
||||
$groupid = 0;
|
||||
if ($this->get_submission_group($userid)) {
|
||||
$group = $this->get_submission_group($userid);
|
||||
if ($group) {
|
||||
$groupid = $group->id;
|
||||
}
|
||||
}
|
||||
$members = $this->get_submission_group_members($groupid, true);
|
||||
foreach ($members as $member) {
|
||||
// User may exist in multple groups (which should put them in the default group).
|
||||
$this->apply_grade_to_user($formdata, $member->id, $attemptnumber);
|
||||
$this->process_outcomes($member->id, $formdata);
|
||||
}
|
||||
} else {
|
||||
$this->apply_grade_to_user($formdata, $userid, $attemptnumber);
|
||||
|
||||
$this->process_outcomes($userid, $formdata);
|
||||
}
|
||||
$maxattemptsreached = !empty($submission) &&
|
||||
$submission->attemptnumber >= ($instance->maxattempts - 1) &&
|
||||
$instance->maxattempts != ASSIGN_UNLIMITED_ATTEMPTS;
|
||||
$shouldreopen = false;
|
||||
if ($instance->attemptreopenmethod == ASSIGN_ATTEMPT_REOPEN_METHOD_UNTILPASS) {
|
||||
// Check the gradetopass from the gradebook.
|
||||
$gradinginfo = grade_get_grades($this->get_course()->id,
|
||||
'mod',
|
||||
'assign',
|
||||
$instance->id,
|
||||
$userid);
|
||||
|
||||
// What do we do if the grade has not been added to the gradebook (e.g. blind marking)?
|
||||
$gradingitem = null;
|
||||
$gradebookgrade = null;
|
||||
if (isset($gradinginfo->items[0])) {
|
||||
$gradingitem = $gradinginfo->items[0];
|
||||
$gradebookgrade = $gradingitem->grades[$userid];
|
||||
}
|
||||
|
||||
if ($gradebookgrade) {
|
||||
// TODO: This code should call grade_grade->is_passed().
|
||||
$shouldreopen = true;
|
||||
if (is_null($gradebookgrade->grade)) {
|
||||
$shouldreopen = false;
|
||||
}
|
||||
if (empty($gradingitem->gradepass) || $gradingitem->gradepass == $gradingitem->grademin) {
|
||||
$shouldreopen = false;
|
||||
}
|
||||
if ($gradebookgrade->grade >= $gradingitem->gradepass) {
|
||||
$shouldreopen = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($instance->attemptreopenmethod == ASSIGN_ATTEMPT_REOPEN_METHOD_MANUAL &&
|
||||
!empty($formdata->addattempt)) {
|
||||
$shouldreopen = true;
|
||||
}
|
||||
// Never reopen if we are editing a previous attempt.
|
||||
if ($attemptnumber != -1) {
|
||||
$shouldreopen = false;
|
||||
}
|
||||
if ($shouldreopen && !$maxattemptsreached) {
|
||||
$this->process_add_attempt($userid);
|
||||
}
|
||||
return $this->save_grade($userid, $formdata);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6288,15 +6422,26 @@ class assign {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new attempt for a user.
|
||||
* Check for a sess key and then call add_attempt.
|
||||
*
|
||||
* @param int $userid int The user to add the attempt for
|
||||
* @return bool - true if successful.
|
||||
*/
|
||||
protected function process_add_attempt($userid) {
|
||||
require_capability('mod/assign:grade', $this->context);
|
||||
require_sesskey();
|
||||
|
||||
return $this->add_attempt($userid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new attempt for a user.
|
||||
*
|
||||
* @param int $userid int The user to add the attempt for
|
||||
* @return bool - true if successful.
|
||||
*/
|
||||
protected function add_attempt($userid) {
|
||||
require_capability('mod/assign:grade', $this->context);
|
||||
|
||||
if ($this->get_instance()->attemptreopenmethod == ASSIGN_ATTEMPT_REOPEN_METHOD_NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -477,4 +477,13 @@ class assign_submission_file extends assign_submission_plugin {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a description of external params suitable for uploading a file submission from a webservice.
|
||||
*
|
||||
* @return external_description|null
|
||||
*/
|
||||
public function get_external_parameters() {
|
||||
return array('files_filemanager' => new external_value(PARAM_INT, 'The id of a draft area containing files for this submission.'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,6 +495,20 @@ class assign_submission_onlinetext extends assign_submission_plugin {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a description of external params suitable for uploading an onlinetext submission from a webservice.
|
||||
*
|
||||
* @return external_description|null
|
||||
*/
|
||||
public function get_external_parameters() {
|
||||
$editorparams = array('text' => new external_value(PARAM_TEXT, 'The text for this submission.'),
|
||||
'format' => new external_value(PARAM_INT, 'The format for this submission'),
|
||||
'itemid' => new external_value(PARAM_INT, 'The draft area id for files attached to the submission'));
|
||||
$editorstructure = new external_single_structure($editorparams);
|
||||
return array('onlinetext_editor' => $editorstructure);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -88,19 +88,21 @@ abstract class assign_submission_plugin extends assign_plugin {
|
||||
/*
|
||||
* Carry out any extra processing required when the work is locked.
|
||||
*
|
||||
* @param stdClass $submission - assign_submission data
|
||||
* @param stdClass|false $submission - assign_submission data if any
|
||||
* @param stdClass $flags - User flags record
|
||||
* @return void
|
||||
*/
|
||||
public function lock(stdClass $submission) {
|
||||
public function lock($submission, stdClass $flags) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Carry out any extra processing required when the work is unlocked.
|
||||
*
|
||||
* @param stdClass $submission - assign_submission data
|
||||
* @param stdClass $submission|false - assign_submission data if any
|
||||
* @param stdClass $flags - User flags record
|
||||
* @return void
|
||||
*/
|
||||
public function unlock(stdClass $submission) {
|
||||
public function unlock($submission, stdClass $flags) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -223,10 +223,6 @@ class mod_assign_base_testcase extends advanced_testcase {
|
||||
*/
|
||||
class testable_assign extends assign {
|
||||
|
||||
public function testable_process_reveal_identities() {
|
||||
return parent::process_reveal_identities();
|
||||
}
|
||||
|
||||
public function testable_show_intro() {
|
||||
return parent::show_intro();
|
||||
}
|
||||
@@ -259,10 +255,6 @@ class testable_assign extends assign {
|
||||
return parent::process_add_attempt($userid);
|
||||
}
|
||||
|
||||
public function testable_process_lock($userid = 0) {
|
||||
return parent::process_lock($userid);
|
||||
}
|
||||
|
||||
public function testable_process_save_quick_grades($postdata) {
|
||||
// Ugly hack to get something into the method.
|
||||
global $_POST;
|
||||
@@ -270,18 +262,6 @@ class testable_assign extends assign {
|
||||
return parent::process_save_quick_grades();
|
||||
}
|
||||
|
||||
public function testable_process_unlock($userid = 0) {
|
||||
return parent::process_unlock($userid);
|
||||
}
|
||||
|
||||
public function testable_process_copy_previous_attempt(&$notices) {
|
||||
return parent::process_copy_previous_attempt($notices);
|
||||
}
|
||||
|
||||
public function testable_process_revert_to_draft($userid = 0) {
|
||||
return parent::process_revert_to_draft($userid);
|
||||
}
|
||||
|
||||
public function testable_process_set_batch_marking_allocation($selectedusers, $markerid) {
|
||||
// Ugly hack to get something into the method.
|
||||
global $_POST;
|
||||
|
||||
@@ -41,7 +41,7 @@ class mod_assign_external_testcase extends externallib_advanced_testcase {
|
||||
/**
|
||||
* Test get_grades
|
||||
*/
|
||||
public function test_get_grades () {
|
||||
public function test_get_grades() {
|
||||
global $DB, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
@@ -118,7 +118,7 @@ class mod_assign_external_testcase extends externallib_advanced_testcase {
|
||||
/**
|
||||
* Test get_assignments
|
||||
*/
|
||||
public function test_get_assignments () {
|
||||
public function test_get_assignments() {
|
||||
global $DB, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
@@ -218,7 +218,7 @@ class mod_assign_external_testcase extends externallib_advanced_testcase {
|
||||
/**
|
||||
* Test get_submissions
|
||||
*/
|
||||
public function test_get_submissions () {
|
||||
public function test_get_submissions() {
|
||||
global $DB, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
@@ -307,7 +307,7 @@ class mod_assign_external_testcase extends externallib_advanced_testcase {
|
||||
/**
|
||||
* Test get_user_flags
|
||||
*/
|
||||
public function test_get_user_flags () {
|
||||
public function test_get_user_flags() {
|
||||
global $DB, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
@@ -378,7 +378,7 @@ class mod_assign_external_testcase extends externallib_advanced_testcase {
|
||||
/**
|
||||
* Test get_user_mappings
|
||||
*/
|
||||
public function test_get_user_mappings () {
|
||||
public function test_get_user_mappings() {
|
||||
global $DB, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
@@ -436,4 +436,592 @@ class mod_assign_external_testcase extends externallib_advanced_testcase {
|
||||
$this->assertEquals($student->id, $mapping['userid']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test lock_submissions
|
||||
*/
|
||||
public function test_lock_submissions() {
|
||||
global $DB, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
// Create a course and assignment and users.
|
||||
$course = self::getDataGenerator()->create_course();
|
||||
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
||||
$params['course'] = $course->id;
|
||||
$params['assignsubmission_onlinetext_enabled'] = 1;
|
||||
$instance = $generator->create_instance($params);
|
||||
$cm = get_coursemodule_from_instance('assign', $instance->id);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assign = new assign($context, $cm, $course);
|
||||
|
||||
$student1 = self::getDataGenerator()->create_user();
|
||||
$student2 = self::getDataGenerator()->create_user();
|
||||
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
|
||||
$this->getDataGenerator()->enrol_user($student1->id,
|
||||
$course->id,
|
||||
$studentrole->id);
|
||||
$this->getDataGenerator()->enrol_user($student2->id,
|
||||
$course->id,
|
||||
$studentrole->id);
|
||||
$teacher = self::getDataGenerator()->create_user();
|
||||
$teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
|
||||
$this->getDataGenerator()->enrol_user($teacher->id,
|
||||
$course->id,
|
||||
$teacherrole->id);
|
||||
|
||||
// Create a student1 with an online text submission.
|
||||
// Simulate a submission.
|
||||
$this->setUser($student1);
|
||||
$submission = $assign->get_user_submission($student1->id, true);
|
||||
$data = new stdClass();
|
||||
$data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
|
||||
'text'=>'Submission text',
|
||||
'format'=>FORMAT_MOODLE);
|
||||
$plugin = $assign->get_submission_plugin_by_type('onlinetext');
|
||||
$plugin->save($submission, $data);
|
||||
|
||||
// Ready to test
|
||||
$this->setUser($teacher);
|
||||
$students = array($student1->id, $student2->id);
|
||||
$result = mod_assign_external::lock_submissions($instance->id, $students);
|
||||
|
||||
// Check for 0 warnings.
|
||||
$this->assertEquals(0, count($result));
|
||||
|
||||
$this->setUser($student2);
|
||||
$submission = $assign->get_user_submission($student2->id, true);
|
||||
$data = new stdClass();
|
||||
$data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
|
||||
'text'=>'Submission text',
|
||||
'format'=>FORMAT_MOODLE);
|
||||
$notices = array();
|
||||
$this->setExpectedException('moodle_exception');
|
||||
$assign->save_submission($data, $notices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test unlock_submissions
|
||||
*/
|
||||
public function test_unlock_submissions() {
|
||||
global $DB, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
// Create a course and assignment and users.
|
||||
$course = self::getDataGenerator()->create_course();
|
||||
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
||||
$params['course'] = $course->id;
|
||||
$params['assignsubmission_onlinetext_enabled'] = 1;
|
||||
$instance = $generator->create_instance($params);
|
||||
$cm = get_coursemodule_from_instance('assign', $instance->id);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assign = new assign($context, $cm, $course);
|
||||
|
||||
$student1 = self::getDataGenerator()->create_user();
|
||||
$student2 = self::getDataGenerator()->create_user();
|
||||
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
|
||||
$this->getDataGenerator()->enrol_user($student1->id,
|
||||
$course->id,
|
||||
$studentrole->id);
|
||||
$this->getDataGenerator()->enrol_user($student2->id,
|
||||
$course->id,
|
||||
$studentrole->id);
|
||||
$teacher = self::getDataGenerator()->create_user();
|
||||
$teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
|
||||
$this->getDataGenerator()->enrol_user($teacher->id,
|
||||
$course->id,
|
||||
$teacherrole->id);
|
||||
|
||||
// Create a student1 with an online text submission.
|
||||
// Simulate a submission.
|
||||
$this->setUser($student1);
|
||||
$submission = $assign->get_user_submission($student1->id, true);
|
||||
$data = new stdClass();
|
||||
$data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
|
||||
'text'=>'Submission text',
|
||||
'format'=>FORMAT_MOODLE);
|
||||
$plugin = $assign->get_submission_plugin_by_type('onlinetext');
|
||||
$plugin->save($submission, $data);
|
||||
|
||||
// Ready to test
|
||||
$this->setUser($teacher);
|
||||
$students = array($student1->id, $student2->id);
|
||||
$result = mod_assign_external::lock_submissions($instance->id, $students);
|
||||
|
||||
// Check for 0 warnings.
|
||||
$this->assertEquals(0, count($result));
|
||||
|
||||
$result = mod_assign_external::unlock_submissions($instance->id, $students);
|
||||
|
||||
// Check for 0 warnings.
|
||||
$this->assertEquals(0, count($result));
|
||||
|
||||
$this->setUser($student2);
|
||||
$submission = $assign->get_user_submission($student2->id, true);
|
||||
$data = new stdClass();
|
||||
$data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
|
||||
'text'=>'Submission text',
|
||||
'format'=>FORMAT_MOODLE);
|
||||
$notices = array();
|
||||
$assign->save_submission($data, $notices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test submit_for_grading
|
||||
*/
|
||||
public function test_submit_for_grading() {
|
||||
global $DB, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
// Create a course and assignment and users.
|
||||
$course = self::getDataGenerator()->create_course();
|
||||
|
||||
set_config('submissionreceipts', 0, 'assign');
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
||||
$params['course'] = $course->id;
|
||||
$params['assignsubmission_onlinetext_enabled'] = 1;
|
||||
$params['submissiondrafts'] = 1;
|
||||
$params['sendnotifications'] = 0;
|
||||
$instance = $generator->create_instance($params);
|
||||
$cm = get_coursemodule_from_instance('assign', $instance->id);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assign = new assign($context, $cm, $course);
|
||||
|
||||
$student1 = self::getDataGenerator()->create_user();
|
||||
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
|
||||
$this->getDataGenerator()->enrol_user($student1->id,
|
||||
$course->id,
|
||||
$studentrole->id);
|
||||
|
||||
// Create a student1 with an online text submission.
|
||||
// Simulate a submission.
|
||||
$this->setUser($student1);
|
||||
$submission = $assign->get_user_submission($student1->id, true);
|
||||
$data = new stdClass();
|
||||
$data->onlinetext_editor = array('itemid'=>file_get_unused_draft_itemid(),
|
||||
'text'=>'Submission text',
|
||||
'format'=>FORMAT_MOODLE);
|
||||
$plugin = $assign->get_submission_plugin_by_type('onlinetext');
|
||||
$plugin->save($submission, $data);
|
||||
|
||||
$result = mod_assign_external::submit_for_grading($instance->id);
|
||||
|
||||
// Check for 0 warnings.
|
||||
$this->assertEquals(0, count($result));
|
||||
|
||||
$submission = $assign->get_user_submission($student1->id, false);
|
||||
|
||||
$this->assertEquals(ASSIGN_SUBMISSION_STATUS_SUBMITTED, $submission->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test save_user_extensions
|
||||
*/
|
||||
public function test_save_user_extensions() {
|
||||
global $DB, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
// Create a course and assignment and users.
|
||||
$course = self::getDataGenerator()->create_course();
|
||||
|
||||
$teacher = self::getDataGenerator()->create_user();
|
||||
$teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
|
||||
$this->getDataGenerator()->enrol_user($teacher->id,
|
||||
$course->id,
|
||||
$teacherrole->id);
|
||||
$this->setUser($teacher);
|
||||
|
||||
$now = time();
|
||||
$yesterday = $now - 24*60*60;
|
||||
$tomorrow = $now + 24*60*60;
|
||||
set_config('submissionreceipts', 0, 'assign');
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
||||
$params['course'] = $course->id;
|
||||
$params['submissiondrafts'] = 1;
|
||||
$params['sendnotifications'] = 0;
|
||||
$params['duedate'] = $yesterday;
|
||||
$params['cutoffdate'] = $now - 10;
|
||||
$instance = $generator->create_instance($params);
|
||||
$cm = get_coursemodule_from_instance('assign', $instance->id);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assign = new assign($context, $cm, $course);
|
||||
|
||||
$student1 = self::getDataGenerator()->create_user();
|
||||
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
|
||||
$this->getDataGenerator()->enrol_user($student1->id,
|
||||
$course->id,
|
||||
$studentrole->id);
|
||||
|
||||
$this->setUser($student1);
|
||||
$result = mod_assign_external::submit_for_grading($instance->id);
|
||||
|
||||
// Check for 0 warnings.
|
||||
$this->assertEquals(1, count($result));
|
||||
|
||||
$this->setUser($teacher);
|
||||
$result = mod_assign_external::save_user_extensions($instance->id, array($student1->id), array($now, $tomorrow));
|
||||
$this->assertEquals(1, count($result));
|
||||
|
||||
$this->setUser($teacher);
|
||||
$result = mod_assign_external::save_user_extensions($instance->id, array($student1->id), array($yesterday - 10));
|
||||
$this->assertEquals(1, count($result));
|
||||
|
||||
$this->setUser($teacher);
|
||||
$result = mod_assign_external::save_user_extensions($instance->id, array($student1->id), array($tomorrow));
|
||||
$this->assertEquals(0, count($result));
|
||||
|
||||
$this->setUser($student1);
|
||||
$result = mod_assign_external::submit_for_grading($instance->id);
|
||||
$this->assertEquals(0, count($result));
|
||||
|
||||
$this->setUser($student1);
|
||||
$result = mod_assign_external::save_user_extensions($instance->id, array($student1->id), array($now, $tomorrow));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reveal_identities
|
||||
*/
|
||||
public function test_reveal_identities() {
|
||||
global $DB, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
// Create a course and assignment and users.
|
||||
$course = self::getDataGenerator()->create_course();
|
||||
|
||||
$teacher = self::getDataGenerator()->create_user();
|
||||
$teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
|
||||
$this->getDataGenerator()->enrol_user($teacher->id,
|
||||
$course->id,
|
||||
$teacherrole->id);
|
||||
$this->setUser($teacher);
|
||||
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
||||
$params['course'] = $course->id;
|
||||
$params['submissiondrafts'] = 1;
|
||||
$params['sendnotifications'] = 0;
|
||||
$params['blindmarking'] = 1;
|
||||
$instance = $generator->create_instance($params);
|
||||
$cm = get_coursemodule_from_instance('assign', $instance->id);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assign = new assign($context, $cm, $course);
|
||||
|
||||
$student1 = self::getDataGenerator()->create_user();
|
||||
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
|
||||
$this->getDataGenerator()->enrol_user($student1->id,
|
||||
$course->id,
|
||||
$studentrole->id);
|
||||
|
||||
$this->setUser($student1);
|
||||
$this->setExpectedException('required_capability_exception');
|
||||
$result = mod_assign_external::reveal_identities($instance->id);
|
||||
$this->assertEquals(1, count($result));
|
||||
$this->assertEquals(true, $assign->is_blind_marking());
|
||||
|
||||
$this->setUser($teacher);
|
||||
$result = mod_assign_external::reveal_identities($instance->id);
|
||||
$this->assertEquals(0, count($result));
|
||||
$this->assertEquals(false, $assign->is_blind_marking());
|
||||
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
||||
$params['course'] = $course->id;
|
||||
$params['submissiondrafts'] = 1;
|
||||
$params['sendnotifications'] = 0;
|
||||
$params['blindmarking'] = 0;
|
||||
$instance = $generator->create_instance($params);
|
||||
$cm = get_coursemodule_from_instance('assign', $instance->id);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assign = new assign($context, $cm, $course);
|
||||
$result = mod_assign_external::reveal_identities($instance->id);
|
||||
$this->assertEquals(1, count($result));
|
||||
$this->assertEquals(false, $assign->is_blind_marking());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test revert_submissions_to_draft
|
||||
*/
|
||||
public function test_revert_submissions_to_draft() {
|
||||
global $DB, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
set_config('submissionreceipts', 0, 'assign');
|
||||
// Create a course and assignment and users.
|
||||
$course = self::getDataGenerator()->create_course();
|
||||
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
||||
$params['course'] = $course->id;
|
||||
$params['sendnotifications'] = 0;
|
||||
$params['submissiondrafts'] = 1;
|
||||
$instance = $generator->create_instance($params);
|
||||
$cm = get_coursemodule_from_instance('assign', $instance->id);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assign = new assign($context, $cm, $course);
|
||||
|
||||
$student1 = self::getDataGenerator()->create_user();
|
||||
$student2 = self::getDataGenerator()->create_user();
|
||||
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
|
||||
$this->getDataGenerator()->enrol_user($student1->id,
|
||||
$course->id,
|
||||
$studentrole->id);
|
||||
$this->getDataGenerator()->enrol_user($student2->id,
|
||||
$course->id,
|
||||
$studentrole->id);
|
||||
$teacher = self::getDataGenerator()->create_user();
|
||||
$teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
|
||||
$this->getDataGenerator()->enrol_user($teacher->id,
|
||||
$course->id,
|
||||
$teacherrole->id);
|
||||
|
||||
// Create a student1 with an online text submission.
|
||||
// Simulate a submission.
|
||||
$this->setUser($student1);
|
||||
$result = mod_assign_external::submit_for_grading($instance->id);
|
||||
$this->assertEquals(0, count($result));
|
||||
|
||||
// Ready to test
|
||||
$this->setUser($teacher);
|
||||
$students = array($student1->id, $student2->id);
|
||||
$result = mod_assign_external::revert_submissions_to_draft($instance->id, array($student1->id));
|
||||
|
||||
// Check for 0 warnings.
|
||||
$this->assertEquals(0, count($result));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test save_submission
|
||||
*/
|
||||
public function test_save_submission() {
|
||||
global $DB, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
// Create a course and assignment and users.
|
||||
$course = self::getDataGenerator()->create_course();
|
||||
|
||||
$teacher = self::getDataGenerator()->create_user();
|
||||
$teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
|
||||
$this->getDataGenerator()->enrol_user($teacher->id,
|
||||
$course->id,
|
||||
$teacherrole->id);
|
||||
$this->setUser($teacher);
|
||||
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
||||
$params['course'] = $course->id;
|
||||
$params['assignsubmission_onlinetext_enabled'] = 1;
|
||||
$params['assignsubmission_file_enabled'] = 1;
|
||||
$params['assignsubmission_file_maxfiles'] = 5;
|
||||
$params['assignsubmission_file_maxsizebytes'] = 1024*1024;
|
||||
$instance = $generator->create_instance($params);
|
||||
$cm = get_coursemodule_from_instance('assign', $instance->id);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assign = new assign($context, $cm, $course);
|
||||
|
||||
$student1 = self::getDataGenerator()->create_user();
|
||||
$student2 = self::getDataGenerator()->create_user();
|
||||
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
|
||||
$this->getDataGenerator()->enrol_user($student1->id,
|
||||
$course->id,
|
||||
$studentrole->id);
|
||||
$this->getDataGenerator()->enrol_user($student2->id,
|
||||
$course->id,
|
||||
$studentrole->id);
|
||||
// Create a student1 with an online text submission.
|
||||
// Simulate a submission.
|
||||
$this->setUser($student1);
|
||||
|
||||
// Create a file in a draft area.
|
||||
$draftidfile = file_get_unused_draft_itemid();
|
||||
|
||||
$usercontext = context_user::instance($student1->id);
|
||||
$filerecord = array(
|
||||
'contextid' => $usercontext->id,
|
||||
'component' => 'user',
|
||||
'filearea' => 'draft',
|
||||
'itemid' => $draftidfile,
|
||||
'filepath' => '/',
|
||||
'filename' => 'testtext.txt',
|
||||
);
|
||||
|
||||
$fs = get_file_storage();
|
||||
$fs->create_file_from_string($filerecord, 'text contents');
|
||||
|
||||
// Create another file in a different draft area.
|
||||
$draftidonlinetext = file_get_unused_draft_itemid();
|
||||
|
||||
$filerecord = array(
|
||||
'contextid' => $usercontext->id,
|
||||
'component' => 'user',
|
||||
'filearea' => 'draft',
|
||||
'itemid' => $draftidonlinetext,
|
||||
'filepath' => '/',
|
||||
'filename' => 'shouldbeanimage.txt',
|
||||
);
|
||||
|
||||
$fs->create_file_from_string($filerecord, 'image contents (not really)');
|
||||
|
||||
// Now try a submission
|
||||
$submissionpluginparams = array();
|
||||
$submissionpluginparams['files_filemanager'] = $draftidfile;
|
||||
$onlinetexteditorparams = array('text'=>'Yeeha!',
|
||||
'format'=>1,
|
||||
'itemid'=>$draftidonlinetext);
|
||||
$submissionpluginparams['onlinetext_editor'] = $onlinetexteditorparams;
|
||||
$result = mod_assign_external::save_submission($instance->id, $submissionpluginparams);
|
||||
|
||||
$this->assertEquals(0, count($result));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test save_grade
|
||||
*/
|
||||
public function test_save_grade() {
|
||||
global $DB, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
// Create a course and assignment and users.
|
||||
$course = self::getDataGenerator()->create_course();
|
||||
|
||||
$teacher = self::getDataGenerator()->create_user();
|
||||
$teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
|
||||
$this->getDataGenerator()->enrol_user($teacher->id,
|
||||
$course->id,
|
||||
$teacherrole->id);
|
||||
$this->setUser($teacher);
|
||||
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
||||
$params['course'] = $course->id;
|
||||
$params['assignfeedback_file_enabled'] = 1;
|
||||
$params['assignfeedback_comments_enabled'] = 1;
|
||||
$instance = $generator->create_instance($params);
|
||||
$cm = get_coursemodule_from_instance('assign', $instance->id);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assign = new assign($context, $cm, $course);
|
||||
|
||||
$student1 = self::getDataGenerator()->create_user();
|
||||
$student2 = self::getDataGenerator()->create_user();
|
||||
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
|
||||
$this->getDataGenerator()->enrol_user($student1->id,
|
||||
$course->id,
|
||||
$studentrole->id);
|
||||
$this->getDataGenerator()->enrol_user($student2->id,
|
||||
$course->id,
|
||||
$studentrole->id);
|
||||
// Simulate a grade.
|
||||
$this->setUser($teacher);
|
||||
|
||||
// Create a file in a draft area.
|
||||
$draftidfile = file_get_unused_draft_itemid();
|
||||
|
||||
$usercontext = context_user::instance($teacher->id);
|
||||
$filerecord = array(
|
||||
'contextid' => $usercontext->id,
|
||||
'component' => 'user',
|
||||
'filearea' => 'draft',
|
||||
'itemid' => $draftidfile,
|
||||
'filepath' => '/',
|
||||
'filename' => 'testtext.txt',
|
||||
);
|
||||
|
||||
$fs = get_file_storage();
|
||||
$fs->create_file_from_string($filerecord, 'text contents');
|
||||
|
||||
// Now try a grade
|
||||
$feedbackpluginparams = array();
|
||||
$feedbackpluginparams['files_filemanager'] = $draftidfile;
|
||||
$feedbackeditorparams = array('text'=>'Yeeha!',
|
||||
'format'=>1);
|
||||
$feedbackpluginparams['assignfeedbackcomments_editor'] = $feedbackeditorparams;
|
||||
$result = mod_assign_external::save_grade($instance->id, $student1->id, 50.0, -1, true, 'released', false, $feedbackpluginparams);
|
||||
|
||||
// No warnings.
|
||||
$this->assertEquals(0, count($result));
|
||||
|
||||
$result = mod_assign_external::get_grades(array($instance->id));
|
||||
|
||||
$this->assertEquals($result['assignments'][0]['grades'][0]['grade'], '50.0');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test copy_previous_attempt
|
||||
*/
|
||||
public function test_copy_previous_attempt() {
|
||||
global $DB, $USER;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
// Create a course and assignment and users.
|
||||
$course = self::getDataGenerator()->create_course();
|
||||
|
||||
$teacher = self::getDataGenerator()->create_user();
|
||||
$teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
|
||||
$this->getDataGenerator()->enrol_user($teacher->id,
|
||||
$course->id,
|
||||
$teacherrole->id);
|
||||
$this->setUser($teacher);
|
||||
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
||||
$params['course'] = $course->id;
|
||||
$params['assignsubmission_onlinetext_enabled'] = 1;
|
||||
$params['assignsubmission_file_enabled'] = 0;
|
||||
$params['assignfeedback_file_enabled'] = 0;
|
||||
$params['attemptreopenmethod'] = 'manual';
|
||||
$params['maxattempts'] = 5;
|
||||
$instance = $generator->create_instance($params);
|
||||
$cm = get_coursemodule_from_instance('assign', $instance->id);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$assign = new assign($context, $cm, $course);
|
||||
|
||||
$student1 = self::getDataGenerator()->create_user();
|
||||
$studentrole = $DB->get_record('role', array('shortname'=>'student'));
|
||||
$this->getDataGenerator()->enrol_user($student1->id,
|
||||
$course->id,
|
||||
$studentrole->id);
|
||||
// Now try a submission
|
||||
$this->setUser($student1);
|
||||
$draftidonlinetext = file_get_unused_draft_itemid();
|
||||
$submissionpluginparams = array();
|
||||
$onlinetexteditorparams = array('text'=>'Yeeha!',
|
||||
'format'=>1,
|
||||
'itemid'=>$draftidonlinetext);
|
||||
$submissionpluginparams['onlinetext_editor'] = $onlinetexteditorparams;
|
||||
$submissionpluginparams['files_filemanager'] = file_get_unused_draft_itemid();
|
||||
$result = mod_assign_external::save_submission($instance->id, $submissionpluginparams);
|
||||
|
||||
$this->setUser($teacher);
|
||||
// Add a grade and reopen the attempt.
|
||||
// Now try a grade
|
||||
$feedbackpluginparams = array();
|
||||
$feedbackpluginparams['files_filemanager'] = file_get_unused_draft_itemid();
|
||||
$feedbackeditorparams = array('text'=>'Yeeha!',
|
||||
'format'=>1);
|
||||
$feedbackpluginparams['assignfeedbackcomments_editor'] = $feedbackeditorparams;
|
||||
$result = mod_assign_external::save_grade($instance->id, $student1->id, 50.0, -1, true, 'released', false, $feedbackpluginparams);
|
||||
|
||||
$this->setUser($student1);
|
||||
// Now copy the previous attempt.
|
||||
$result = mod_assign_external::copy_previous_attempt($instance->id);
|
||||
// No warnings.
|
||||
$this->assertEquals(0, count($result));
|
||||
|
||||
$this->setUser($teacher);
|
||||
$result = mod_assign_external::get_submissions(array($instance->id));
|
||||
|
||||
// Check we are now on the second attempt.
|
||||
$this->assertEquals($result['assignments'][0]['submissions'][0]['attemptnumber'], 1);
|
||||
// Check the plugins data is not empty.
|
||||
$this->assertNotEmpty($result['assignments'][0]['submissions'][0]['plugins']);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,26 +83,31 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
|
||||
|
||||
// Test students cannot reveal identities.
|
||||
$nopermission = false;
|
||||
$this->students[0]->ignoresesskey = true;
|
||||
$this->setUser($this->students[0]);
|
||||
$this->setExpectedException('required_capability_exception');
|
||||
$assign->testable_process_reveal_identities();
|
||||
$assign->reveal_identities();
|
||||
$this->students[0]->ignoresesskey = false;
|
||||
|
||||
// Test teachers cannot reveal identities.
|
||||
$nopermission = false;
|
||||
$this->teachers[0]->ignoresesskey = true;
|
||||
$this->setUser($this->teachers[0]);
|
||||
$this->setExpectedException('required_capability_exception');
|
||||
$assign->testable_process_reveal_identities();
|
||||
$assign->reveal_identities();
|
||||
$this->teachers[0]->ignoresesskey = false;
|
||||
|
||||
// Test sesskey is required.
|
||||
$this->setUser($this->editingteachers[0]);
|
||||
$this->setExpectedException('moodle_exception');
|
||||
$assign->testable_process_reveal_identities();
|
||||
$assign->reveal_identities();
|
||||
|
||||
// Test editingteacher can reveal identities if sesskey is ignored.
|
||||
$this->editingteachers[0]->ignoresesskey = true;
|
||||
$this->setUser($this->editingteachers[0]);
|
||||
$assign->testable_process_reveal_identities();
|
||||
$assign->reveal_identities();
|
||||
$this->assertEquals(false, $assign->is_blind_marking());
|
||||
$this->editingteachers[0]->ignoresesskey = false;
|
||||
|
||||
// Test student names are visible.
|
||||
$gradingtable = new assign_grading_table($assign, 1, '', 0, true);
|
||||
@@ -1016,7 +1021,7 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
|
||||
$assign = $this->create_instance();
|
||||
$sink = $this->redirectEvents();
|
||||
|
||||
$assign->testable_process_lock($this->students[0]->id);
|
||||
$assign->lock_submission($this->students[0]->id);
|
||||
|
||||
$events = $sink->get_events();
|
||||
$this->assertCount(1, $events);
|
||||
@@ -1049,7 +1054,7 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
|
||||
$assign = $this->create_instance(array('blindmarking'=>1));
|
||||
$sink = $this->redirectEvents();
|
||||
|
||||
$assign->testable_process_reveal_identities();
|
||||
$assign->reveal_identities();
|
||||
|
||||
$events = $sink->get_events();
|
||||
$this->assertCount(1, $events);
|
||||
@@ -1083,7 +1088,7 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
|
||||
$assign->testable_update_submission($submission, $this->students[0]->id, true, false);
|
||||
|
||||
$sink = $this->redirectEvents();
|
||||
$assign->testable_process_revert_to_draft($this->students[0]->id);
|
||||
$assign->revert_to_draft($this->students[0]->id);
|
||||
|
||||
$events = $sink->get_events();
|
||||
$this->assertCount(1, $events);
|
||||
@@ -1191,7 +1196,7 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
|
||||
|
||||
$sink = $this->redirectEvents();
|
||||
$notices = null;
|
||||
$assign->testable_process_copy_previous_attempt($notices);
|
||||
$assign->copy_previous_attempt($notices);
|
||||
|
||||
$events = $sink->get_events();
|
||||
$this->assertCount(1, $events);
|
||||
@@ -1221,7 +1226,7 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
|
||||
$assign = $this->create_instance();
|
||||
$sink = $this->redirectEvents();
|
||||
|
||||
$assign->testable_process_unlock($this->students[0]->id);
|
||||
$assign->unlock_submission($this->students[0]->id);
|
||||
|
||||
$events = $sink->get_events();
|
||||
$this->assertCount(1, $events);
|
||||
|
||||
@@ -3,6 +3,11 @@ This files describes API changes in the assign code.
|
||||
=== 2.6 ===
|
||||
* To see submission/grades of inactive users, user should have moodle/course:viewsuspendedusers capability.
|
||||
* count_* functions will return only active participants.
|
||||
* assign_submission_plugin->lock and unlock methods have an additional parameter for user flags. A user will not
|
||||
always have a submission record when the submission is locked/unlocked.
|
||||
* Submission and feedback plugins can now participate in webservices. The plugin must implement get_external_parameters()
|
||||
to describe the parameters it is expecting from the mod_assign_save_grade or mod_assign_save_submission functions. The
|
||||
plugin will then handle the webservice via it's normal save() method with the extra data supplied in the $data argument.
|
||||
|
||||
=== 2.5 ===
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$module->component = 'mod_assign'; // Full name of the plugin (used for diagnostics).
|
||||
$module->version = 2013070902; // The current module version (Date: YYYYMMDDXX).
|
||||
$module->version = 2013080800; // The current module version (Date: YYYYMMDDXX).
|
||||
$module->requires = 2013050100; // Requires this Moodle version.
|
||||
$module->cron = 60;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user