Merge branch 'MDL-31284-POST23' of git://github.com/netspotau/moodle-mod_assign

This commit is contained in:
Aparup Banerjee 2012-09-06 19:36:24 +08:00
commit 89577d774d
11 changed files with 783 additions and 125 deletions

View File

@ -56,7 +56,11 @@ class backup_assign_activity_structure_step extends backup_activity_structure_st
'allowsubmissionsfromdate',
'grade',
'timemodified',
'completionsubmit'));
'completionsubmit',
'requiresubmissionstatement',
'teamsubmission',
'requireallteammemberssubmit',
'teamsubmissiongroupingid'));
$submissions = new backup_nested_element('submissions');
@ -64,7 +68,8 @@ class backup_assign_activity_structure_step extends backup_activity_structure_st
array('userid',
'timecreated',
'timemodified',
'status'));
'status',
'groupid'));
$grades = new backup_nested_element('grades');
@ -116,8 +121,10 @@ class backup_assign_activity_structure_step extends backup_activity_structure_st
// Define id annotations
$submission->annotate_ids('user', 'userid');
$submission->annotate_ids('group', 'groupid');
$grade->annotate_ids('user', 'userid');
$grade->annotate_ids('user', 'grader');
$assign->annotate_ids('grouping', 'teamsubmissiongroupingid');
// Define file annotations
$assign->annotate_files('mod_assign', 'intro', null); // This file area hasn't itemid

View File

@ -73,6 +73,9 @@ class restore_assign_activity_structure_step extends restore_activity_structure_
$data->timemodified = $this->apply_date_offset($data->timemodified);
$data->allowsubmissionsfromdate = $this->apply_date_offset($data->allowsubmissionsfromdate);
$data->duedate = $this->apply_date_offset($data->duedate);
if ($data->teamsubmissiongroupingid > 0) {
$data->teamsubmissiongroupingid = $this->get_mappingid('grouping', $data->teamsubmissiongroupingid);
}
if (!isset($data->cutoffdate)) {
$data->cutoffdate = 0;
@ -105,7 +108,12 @@ class restore_assign_activity_structure_step extends restore_activity_structure_
$data->timemodified = $this->apply_date_offset($data->timemodified);
$data->timecreated = $this->apply_date_offset($data->timecreated);
$data->userid = $this->get_mappingid('user', $data->userid);
if ($data->userid > 0) {
$data->userid = $this->get_mappingid('user', $data->userid);
}
if ($data->groupid > 0) {
$data->groupid = $this->get_mappingid('group', $data->groupid);
}
$newitemid = $DB->insert_record('assign_submission', $data);

View File

@ -22,13 +22,17 @@
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The time the settings for this assign module instance were last modified." PREVIOUS="grade" NEXT="requiresubmissionstatement"/>
<FIELD NAME="requiresubmissionstatement" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Forces the student to accept a submission statement when submitting an assignment" PREVIOUS="timemodified" NEXT="completionsubmit"/>
<FIELD NAME="completionsubmit" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If this field is set to 1, then the activity will be automatically marked as 'complete' once the user submits their assignment." PREVIOUS="requiresubmissionstatement" NEXT="cutoffdate"/>
<FIELD NAME="cutoffdate" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The final date after which submissions will no longer be accepted for this assignment without an extensions." PREVIOUS="completionsubmit"/>
<FIELD NAME="cutoffdate" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The final date after which submissions will no longer be accepted for this assignment without an extensions." PREVIOUS="completionsubmit" NEXT="teamsubmission"/>
<FIELD NAME="teamsubmission" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Do students submit in teams?" PREVIOUS="cutoffdate" NEXT="requireallteammemberssubmit"/>
<FIELD NAME="requireallteammemberssubmit" TYPE="int" LENGTH="2" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="If enabled, a submission will not be accepted until all team members have submitted it." PREVIOUS="teamsubmission" NEXT="teamsubmissiongroupingid"/>
<FIELD NAME="teamsubmissiongroupingid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="A grouping id to get groups for team submissions" PREVIOUS="requireallteammemberssubmit"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="The unique id for this assignment instance."/>
</KEYS>
<INDEXES>
<INDEX NAME="course" UNIQUE="false" FIELDS="course" COMMENT="The course this assignment instance belongs to."/>
<INDEX NAME="course" UNIQUE="false" FIELDS="course" COMMENT="The course this assignment instance belongs to." NEXT="teamsubmissiongroupingid"/>
<INDEX NAME="teamsubmissiongroupingid" UNIQUE="false" FIELDS="teamsubmissiongroupingid" COMMENT="The grouping id for team submissions" PREVIOUS="course"/>
</INDEXES>
</TABLE>
<TABLE NAME="assign_submission" COMMENT="This table keeps information about student interactions with the mod/assign. This is limited to metadata about a student submission but does not include the submission itself which is stored by plugins." PREVIOUS="assign" NEXT="assign_grades">
@ -38,7 +42,8 @@
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="assignment" NEXT="timecreated"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The time of the first student submission to this assignment." PREVIOUS="userid" NEXT="timemodified"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The last time this assignment submission was modified by a student." PREVIOUS="timecreated" NEXT="status"/>
<FIELD NAME="status" TYPE="char" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="The status of this assignment submission. The current statuses are DRAFT and SUBMITTED." PREVIOUS="timemodified"/>
<FIELD NAME="status" TYPE="char" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="The status of this assignment submission. The current statuses are DRAFT and SUBMITTED." PREVIOUS="timemodified" NEXT="groupid"/>
<FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="The group id for team submissions" PREVIOUS="status"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="The unique id for this assignment submission." NEXT="assignment"/>
@ -90,4 +95,4 @@
</INDEXES>
</TABLE>
</TABLES>
</XMLDB>
</XMLDB>

View File

@ -34,11 +34,11 @@ function xmldb_assign_upgrade($oldversion) {
if ($oldversion < 2012051700) {
// Define field sendlatenotifications to be added to assign
// Define field to be added to assign.
$table = new xmldb_table('assign');
$field = new xmldb_field('sendlatenotifications', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'sendnotifications');
// Conditionally launch add field sendlatenotifications
// Conditionally launch add field.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
@ -47,16 +47,17 @@ function xmldb_assign_upgrade($oldversion) {
upgrade_mod_savepoint(true, 2012051700, 'assign');
}
// Moodle v2.3.0 release upgrade line
// Put any upgrade step following this
// Moodle v2.3.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2012071800) {
// Define field requiresubmissionstatement to be added to assign
// Define field requiresubmissionstatement to be added to assign.
$table = new xmldb_table('assign');
$field = new xmldb_field('requiresubmissionstatement', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'timemodified');
// Conditionally launch add field requiresubmissionstatement
// Conditionally launch add field requiresubmissionstatement.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
@ -67,11 +68,11 @@ function xmldb_assign_upgrade($oldversion) {
if ($oldversion < 2012081600) {
// Define field sendlatenotifications to be added to assign.
// Define field to be added to assign.
$table = new xmldb_table('assign');
$field = new xmldb_field('completionsubmit', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'timemodified');
// Conditionally launch add field sendlatenotifications.
// Conditionally launch add field.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
@ -118,6 +119,44 @@ function xmldb_assign_upgrade($oldversion) {
upgrade_mod_savepoint(true, 2012082100, 'assign');
}
// Team assignment support.
if ($oldversion < 2012082300) {
// Define field to be added to assign.
$table = new xmldb_table('assign');
$field = new xmldb_field('teamsubmission', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED,
XMLDB_NOTNULL, null, '0', 'cutoffdate');
// Conditionally launch add field.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
$field = new xmldb_field('requireallteammemberssubmit', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED,
XMLDB_NOTNULL, null, '0', 'teamsubmission');
// Conditionally launch add field.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
$field = new xmldb_field('teamsubmissiongroupingid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED,
XMLDB_NOTNULL, null, '0', 'requireallteammemberssubmit');
// Conditionally launch add field.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
$index = new xmldb_index('teamsubmissiongroupingid', XMLDB_INDEX_NOTUNIQUE, array('teamsubmissiongroupingid'));
// Conditionally launch add index.
if (!$dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}
$table = new xmldb_table('assign_submission');
$field = new xmldb_field('groupid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'status');
// Conditionally launch add field.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
upgrade_mod_savepoint(true, 2012082300, 'assign');
}
return true;
}

View File

@ -52,6 +52,11 @@ class assign_grading_table extends table_sql implements renderable {
private $quickgrading = false;
/** @var boolean $hasgrantextension - Only do the capability check once for the entire table */
private $hasgrantextension = false;
/** @var array $groupsubmissions - A static cache of group submissions */
private $groupsubmissions = array();
/** @var array $submissiongroups - A static cache of submission groups */
private $submissiongroups = array();
/**
* overridden constructor keeps a reference to the assignment class that is displaying this table
@ -153,6 +158,14 @@ class assign_grading_table extends table_sql implements renderable {
$headers[] = get_string('status');
}
// Team submission columns
if ($assignment->get_instance()->teamsubmission) {
$columns[] = 'team';
$headers[] = get_string('submissionteam', 'assign');
$columns[] = 'teamstatus';
$headers[] = get_string('teamsubmissionstatus', 'assign');
}
// Grade
$columns[] = 'grade';
@ -205,6 +218,11 @@ class assign_grading_table extends table_sql implements renderable {
$this->no_sorting('select');
$this->no_sorting('outcomes');
if ($assignment->get_instance()->teamsubmission) {
$this->no_sorting('team');
$this->no_sorting('teamstatus');
}
foreach ($this->assignment->get_submission_plugins() as $plugin) {
if ($plugin->is_visible() && $plugin->is_enabled()) {
$this->no_sorting('assignsubmission_' . $plugin->get_type());
@ -254,6 +272,71 @@ class assign_grading_table extends table_sql implements renderable {
return $o;
}
/**
* Get the team info for this user
*
* @param stdClass $row
* @return string The team name
*/
function col_team(stdClass $row) {
$submission = false;
$group = false;
$this->get_group_and_submission($row->id, $group, $submission);
if ($group) {
return $group->name;
}
return get_string('defaultteam', 'assign');
}
/**
* Use a static cache to try and reduce DB calls.
*
* @param int $userid The user id for this submission
* @param int $groupid The groupid (returned)
* @param mixed $submission The stdClass submission or false (returned)
*/
function get_group_and_submission($userid, &$group, &$submission) {
$group = false;
if (isset($this->submissiongroups[$userid])) {
$group = $this->submissiongroups[$userid];
} else {
$group = $this->assignment->get_submission_group($userid, false);
$this->submissiongroups[$userid] = $group;
}
$groupid = 0;
if ($group) {
$groupid = $group->id;
}
if (isset($this->groupsubmissions[$groupid])) {
$submission = $this->groupsubmissions[$groupid];
} else {
$submission = $this->assignment->get_group_submission($userid, $groupid, false);
$this->groupsubmissions[$groupid] = $submission;
}
}
/**
* Get the team status for this user
*
* @param stdClass $row
* @return string The team name
*/
function col_teamstatus(stdClass $row) {
$submission = false;
$group = false;
$this->get_group_and_submission($row->id, $group, $submission);
$status = '';
if ($submission) {
$status = $submission->status;
}
return get_string('submissionstatus_' . $status, 'assign');
}
/**
* Format a list of outcomes
*
@ -605,7 +688,15 @@ class assign_grading_table extends table_sql implements renderable {
$plugin = $this->assignment->get_submission_plugin_by_type(substr($colname, strlen('assignsubmission_')));
if ($plugin->is_visible() && $plugin->is_enabled()) {
if ($row->submissionid) {
if ($this->assignment->get_instance()->teamsubmission) {
$group = false;
$submission = false;
$this->get_group_and_submission($row->id, $group, $submission);
if ($submission) {
return $this->format_plugin_summary_with_link($plugin, $submission, 'grading', array());
}
} else if ($row->submissionid) {
$submission = new stdClass();
$submission->id = $row->submissionid;
$submission->timecreated = $row->firstsubmission;

View File

@ -32,6 +32,7 @@ $string['allowsubmissionsfromdatesummary'] = 'This assignment will accept submis
$string['allowsubmissionsanddescriptionfromdatesummary'] = 'The assignment details and submission form will be available from <strong>{$a}</strong>';
$string['alwaysshowdescription'] = 'Always show description';
$string['alwaysshowdescription_help'] = 'If disabled, the Assignment Description above will only become visible to students at the "Allow submissions from" date.';
$string['applytoteam'] = 'Apply grades and feedback to entire team';
$string['assign:addinstance'] = 'Add a new assignment';
$string['assign:exportownsubmission'] = 'Export own submission';
$string['assign:grade'] = 'Grade assignment';
@ -86,6 +87,7 @@ $string['cutoffdatevalidation'] = 'Cut-off date must be after the due date.';
$string['cutoffdatefromdatevalidation'] = 'Cut-off date must be after the allow submissions from date.';
$string['defaultplugins'] = 'Default assignment settings';
$string['defaultplugins_help'] = 'These settings define the defaults for all new assignments.';
$string['defaultteam'] = 'Default team';
$string['deletepluginareyousure'] = 'Delete assignment plugin {$a}: are you sure?';
$string['deletepluginareyousuremessage'] = 'You are about to completely delete the assignment plugin {$a}. This will completely delete everything in the database associated with this assignment plugin. Are you SURE you want to continue?';
$string['deletingplugin'] = 'Deleting plugin {$a}.';
@ -193,6 +195,7 @@ $string['numberofdraftsubmissions'] = 'Drafts';
$string['numberofparticipants'] = 'Participants';
$string['numberofsubmittedassignments'] = 'Submitted';
$string['numberofsubmissionsneedgrading'] = 'Needs grading';
$string['numberofteams'] = 'Teams';
$string['offline'] = 'No online submissions required';
$string['open'] = 'Open';
$string['overdue'] = '<font color="red">Assignment is overdue by: {$a}</font>';
@ -210,6 +213,8 @@ $string['quickgradingchangessaved'] = 'The grade changes were saved';
$string['quickgrading_help'] = 'Quick grading allows you to assign grades (and outcomes) directly in the submissions table. Quick grading is not compatible with advanced grading and is not recommended when there are multiple markers.';
$string['requiresubmissionstatement'] = 'Require that students accept the submission statement';
$string['requiresubmissionstatement_help'] = 'Require that students accept the submission statement for all assignment submissions for this entire Moodle installation. If this setting is not enabled, then submission statements can be enabled or disabled in the settings for each assignment.';
$string['requireallteammemberssubmit'] = 'Require all team members submit';
$string['requireallteammemberssubmit_help'] = 'If enabled, all members of the student team must click the submit button for this assignment before the team submission will be considered as submitted. If disabled, the team submission will be considered as submitted as soon as any member of the student team clicks the submit button.';
$string['reverttodraftforstudent'] = 'Revert submission to draft for student: (id={$a->id}, fullname={$a->fullname}).';
$string['reverttodraft'] = 'Revert the submission to draft status.';
$string['reverttodraftshort'] = 'Revert the submission to draft';
@ -259,6 +264,7 @@ $string['submissionstatus_new'] = 'New submission';
$string['submissionstatus_'] = 'No submission';
$string['submissionstatus'] = 'Submission status';
$string['submissionstatus_submitted'] = 'Submitted for grading';
$string['submissionteam'] = 'Team';
$string['submission'] = 'Submission';
$string['submitaction'] = 'Submit';
$string['submitassignment_help'] = 'Once this assignment is submitted you will not be able to make any more changes';
@ -267,6 +273,11 @@ $string['submittedearly'] = 'Assignment was submitted {$a} early';
$string['submittedlate'] = 'Assignment was submitted {$a} late';
$string['submittedlateshort'] = '{$a} late';
$string['submitted'] = 'Submitted';
$string['teamsubmission'] = 'Students submit in teams';
$string['teamsubmission_help'] = 'If enabled students will be divided into teams based on the default set of groups or a custom grouping. A team submission will be shared among team members and all members of the team will see each others changes to the submission.';
$string['teamsubmissiongroupingid'] = 'Grouping for student teams';
$string['teamsubmissiongroupingid_help'] = 'This is the grouping that the assignment will use to find groups for student teams. If not set - the default set of groups will be used.';
$string['teamsubmissionstatus'] = 'Team submission status';
$string['textinstructions'] = 'Assignment instructions';
$string['timemodified'] = 'Last modified';
$string['timeremaining'] = 'Time remaining';
@ -276,6 +287,7 @@ $string['updategrade'] = 'Update grade';
$string['updatetable'] = 'Save and update table';
$string['upgradenotimplemented'] = 'Upgrade not implemented in plugin ({$a->type} {$a->subtype})';
$string['userextensiondate'] = 'Extension granted until: {$a}';
$string['userswhoneedtosubmit'] = 'Users who need to submit: {$a}';
$string['viewfeedback'] = 'View feedback';
$string['viewfeedbackforuser'] = 'View feedback for user: {$a}';
$string['viewfullgradingpage'] = 'Open the full grading page to provide feedback';

View File

@ -424,6 +424,10 @@ class assign {
$update->allowsubmissionsfromdate = $formdata->allowsubmissionsfromdate;
$update->grade = $formdata->grade;
$update->completionsubmit = !empty($formdata->completionsubmit);
$update->teamsubmission = $formdata->teamsubmission;
$update->requireallteammemberssubmit = $formdata->requireallteammemberssubmit;
$update->teamsubmissiongroupingid = $formdata->teamsubmissiongroupingid;
$returnid = $DB->insert_record('assign', $update);
$this->instance = $DB->get_record('assign', array('id'=>$returnid), '*', MUST_EXIST);
// cache the course record
@ -644,6 +648,10 @@ class assign {
$update->allowsubmissionsfromdate = $formdata->allowsubmissionsfromdate;
$update->grade = $formdata->grade;
$update->completionsubmit = !empty($formdata->completionsubmit);
$update->teamsubmission = $formdata->teamsubmission;
$update->requireallteammemberssubmit = $formdata->requireallteammemberssubmit;
$update->teamsubmissiongroupingid = $formdata->teamsubmissiongroupingid;
$result = $DB->update_record('assign', $update);
$this->instance = $DB->get_record('assign', array('id'=>$update->id), '*', MUST_EXIST);
@ -970,6 +978,24 @@ class assign {
}
}
/**
* Load a count of valid teams for this assignment
*
* @return int number of valid teams
*/
public function count_teams() {
$groups = groups_get_all_groups($this->get_course()->id, 0, $this->get_instance()->teamsubmissiongroupingid, 'g.id');
$count = count($groups);
// See if there are any users in the default group.
$defaultusers = $this->get_submission_group_members(0, true);
if (count($defaultusers) > 0) {
$count += 1;
}
return $count;
}
/**
* Load a count of users enrolled in the current course with the specified permission and group (0 for no group)
*
@ -1009,10 +1035,15 @@ class assign {
*/
public function count_submissions_with_status($status) {
global $DB;
return $DB->count_records_sql("SELECT COUNT('x')
FROM {assign_submission}
WHERE assignment = ? AND
status = ?", array($this->get_course_module()->instance, $status));
$sql = 'SELECT COUNT(id) FROM {assign_submission} WHERE assignment = ? AND status = ?';
$params = array($this->get_course_module()->instance, $status);
if ($this->get_instance()->teamsubmission) {
// only look at team submissions
$sql .= ' AND userid = ?';
$params[] = 0;
}
return $DB->count_records_sql($sql, $params);
}
/**
@ -1021,7 +1052,7 @@ class assign {
*
* @return array An array of userids
*/
private function get_grading_userid_list(){
private function get_grading_userid_list() {
$filter = get_user_preferences('assign_filter', '');
$table = new assign_grading_table($this, 0, $filter, 0, false);
@ -1039,7 +1070,7 @@ class assign {
* @param bool $last This is set to true if this is the last user in the table
* @return mixed The user id of the matching user or false if there was an error
*/
private function get_userid_for_row($num, $last){
private function get_userid_for_row($num, $last) {
if (!array_key_exists('userid_for_row', $this->cache)) {
$this->cache['userid_for_row'] = array();
}
@ -1325,6 +1356,142 @@ class assign {
return $o;
}
/**
* Get a list of the users in the same group as this user
*
* @param int $groupid The id of the group whose members we want or 0 for the default group
* @param bool $onlyids Whether to retrieve only the user id's
* @return array The users (possibly id's only)
*/
public function get_submission_group_members($groupid, $onlyids) {
$members = array();
if ($groupid != 0) {
if ($onlyids) {
$allusers = groups_get_members($groupid, 'u.id');
} else {
$allusers = groups_get_members($groupid);
}
foreach ($allusers as $user) {
if ($this->get_submission_group($user->id)) {
$members[] = $user;
}
}
} else {
$allusers = $this->list_participants(null, $onlyids);
foreach ($allusers as $user) {
if ($this->get_submission_group($user->id) == null) {
$members[] = $user;
}
}
}
return $members;
}
/**
* Get a list of the users in the same group as this user that have not submitted the assignment
*
* @param int $groupid The id of the group whose members we want or 0 for the default group
* @param bool $onlyids Whether to retrieve only the user id's
* @return array The users (possibly id's only)
*/
public function get_submission_group_members_who_have_not_submitted($groupid, $onlyids) {
if (!$this->get_instance()->teamsubmission || !$this->get_instance()->requireallteammemberssubmit) {
return array();
}
$members = $this->get_submission_group_members($groupid, $onlyids);
foreach ($members as $id => $member) {
$submission = $this->get_user_submission($member->id, false);
if ($submission && $submission->status != ASSIGN_SUBMISSION_STATUS_DRAFT) {
unset($members[$id]);
}
}
return $members;
}
/**
* Load the group submission object for a particular user, optionally creating it if required
*
* This will create the user submission and the group submission if required
*
* @param int $userid The id of the user whose submission we want
* @param int $groupid The id of the group for this user - may be 0 in which case it is determined from the userid
* @param bool $create If set to true a new submission object will be created in the database
* @return stdClass The submission
*/
public function get_group_submission($userid, $groupid, $create) {
global $DB;
if ($groupid == 0) {
$group = $this->get_submission_group($userid);
if ($group) {
$groupid = $group->id;
}
}
if ($create) {
// Make sure there is a submission for this user.
$params = array('assignment'=>$this->get_instance()->id, 'groupid'=>0, 'userid'=>$userid);
$submission = $DB->get_record('assign_submission', $params);
if (!$submission) {
$submission = new stdClass();
$submission->assignment = $this->get_instance()->id;
$submission->userid = $userid;
$submission->groupid = 0;
$submission->timecreated = time();
$submission->timemodified = $submission->timecreated;
if ($this->get_instance()->submissiondrafts) {
$submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
} else {
$submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
}
$DB->insert_record('assign_submission', $submission);
}
}
// Now get the group submission.
$params = array('assignment'=>$this->get_instance()->id, 'groupid'=>$groupid, 'userid'=>0);
$submission = $DB->get_record('assign_submission', $params);
if ($submission) {
return $submission;
}
if ($create) {
$submission = new stdClass();
$submission->assignment = $this->get_instance()->id;
$submission->userid = 0;
$submission->groupid = $groupid;
$submission->timecreated = time();
$submission->timemodified = $submission->timecreated;
if ($this->get_instance()->submissiondrafts) {
$submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
} else {
$submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
}
$sid = $DB->insert_record('assign_submission', $submission);
$submission->id = $sid;
return $submission;
}
return false;
}
/**
* This is used for team assignments to get the group for the specified user.
* If the user is a member of multiple or no groups this will return false
*
* @param int $userid The id of the user whose submission we want
* @return mixed The group or false
*/
public function get_submission_group($userid) {
$groups = groups_get_all_groups($this->get_course()->id, $userid, $this->get_instance()->teamsubmissiongroupingid);
if (count($groups) != 1) {
return false;
}
return array_pop($groups);
}
/**
* display the submission that is used by a plugin
@ -1564,6 +1731,10 @@ class assign {
/**
* Load the submission object for a particular user, optionally creating it if required
*
* For team assignments there are 2 submissions - the student submission and the team submission
* All files are associated with the team submission but the status of the students contribution is
* recorded separately.
*
* @param int $userid The id of the user whose submission we want or 0 in which case USER->id is used
* @param bool $create optional Defaults to false. If set to true a new submission object will be created in the database
* @return stdClass The submission
@ -1574,8 +1745,9 @@ class assign {
if (!$userid) {
$userid = $USER->id;
}
// if the userid is not null then use userid
$submission = $DB->get_record('assign_submission', array('assignment'=>$this->get_instance()->id, 'userid'=>$userid));
// If the userid is not null then use userid.
$params = array('assignment'=>$this->get_instance()->id, 'userid'=>$userid, 'groupid'=>0);
$submission = $DB->get_record('assign_submission', $params);
if ($submission) {
return $submission;
@ -1696,7 +1868,7 @@ class assign {
if ($offset) {
$_POST = array();
}
if(!$userid){
if (!$userid) {
throw new coding_exception('Row is out of bounds for the current grading table: ' . $rownum);
}
$user = $DB->get_record('user', array('id' => $userid));
@ -1704,6 +1876,21 @@ class assign {
$o .= $this->output->render(new assign_user_summary($user, $this->get_course()->id, has_capability('moodle/site:viewfullnames', $this->get_course_context())));
}
$submission = $this->get_user_submission($userid, false);
$submissiongroup = null;
$submissiongroupmemberswhohavenotsubmitted = array();
$teamsubmission = null;
$notsubmitted = array();
if ($this->get_instance()->teamsubmission) {
$teamsubmission = $this->get_group_submission($userid, 0, false);
$submissiongroup = $this->get_submission_group($userid);
$groupid = 0;
if ($submissiongroup) {
$groupid = $submissiongroup->id;
}
$notsubmitted = $this->get_submission_group_members_who_have_not_submitted($groupid, false);
}
// get the current grade
$grade = $this->get_user_grade($userid, false);
if ($this->can_view_submission($userid)) {
@ -1715,11 +1902,20 @@ class assign {
$showedit = has_capability('mod/assign:submit', $this->context) &&
$this->submissions_open($userid) && ($this->is_any_submission_plugin_enabled());
$showsubmit = $showedit && $submission && ($submission->status == ASSIGN_SUBMISSION_STATUS_DRAFT);
if ($teamsubmission) {
$showsubmit = $showedit && $teamsubmission && ($teamsubmission->status == ASSIGN_SUBMISSION_STATUS_DRAFT);
} else {
$showsubmit = $showedit && $submission && ($submission->status == ASSIGN_SUBMISSION_STATUS_DRAFT);
}
$viewfullnames = has_capability('moodle/site:viewfullnames', $this->get_course_context());
$o .= $this->output->render(new assign_submission_status($this->get_instance()->allowsubmissionsfromdate,
$this->get_instance()->alwaysshowdescription,
$submission,
$this->get_instance()->teamsubmission,
$teamsubmission,
$submissiongroup,
$notsubmitted,
$this->is_any_submission_plugin_enabled(),
$gradelocked,
$this->is_graded($userid),
@ -1729,10 +1925,13 @@ class assign {
$this->get_return_action(),
$this->get_return_params(),
$this->get_course_module()->id,
$this->get_course()->id,
assign_submission_status::GRADER_VIEW,
$showedit,
$showsubmit,
$extensionduedate));
$viewfullnames,
$extensionduedate,
$this->get_context()));
}
if ($grade) {
$data = new stdClass();
@ -1746,11 +1945,18 @@ class assign {
// now show the grading form
if (!$mform) {
$mform = new mod_assign_grade_form(null, array($this, $data, array('rownum'=>$rownum, 'useridlist'=>$useridlist, 'last'=>$last)), 'post', '', array('class'=>'gradeform'));
$pagination = array( 'rownum'=>$rownum, 'useridlist'=>$useridlist, 'last'=>$last);
$formparams = array($this, $data, $pagination);
$mform = new mod_assign_grade_form(null,
$formparams,
'post',
'',
array('class'=>'gradeform'));
}
$o .= $this->output->render(new assign_form('gradingform',$mform));
$this->add_to_log('view grading form', get_string('viewgradingformforstudent', 'assign', array('id'=>$user->id, 'fullname'=>fullname($user))));
$msg = get_string('viewgradingformforstudent', 'assign', array('id'=>$user->id, 'fullname'=>fullname($user)));
$this->add_to_log('view grading form', $msg);
$o .= $this->view_footer();
return $o;
@ -2113,18 +2319,43 @@ class assign {
$submission = $this->get_user_submission($user->id, false);
$o = '';
$teamsubmission = null;
$submissiongroup = null;
$notsubmitted = array();
if ($this->get_instance()->teamsubmission) {
$teamsubmission = $this->get_group_submission($user->id, 0, false);
$submissiongroup = $this->get_submission_group($user->id);
$groupid = 0;
if ($submissiongroup) {
$groupid = $submissiongroup->id;
}
$notsubmitted = $this->get_submission_group_members_who_have_not_submitted($groupid, false);
}
if ($this->can_view_submission($user->id)) {
$showedit = has_capability('mod/assign:submit', $this->context) &&
$this->submissions_open($user->id) && ($this->is_any_submission_plugin_enabled()) && $showlinks;
$showsubmit = $submission && ($submission->status == ASSIGN_SUBMISSION_STATUS_DRAFT) && $showlinks;
$gradelocked = ($grade && $grade->locked) || $this->grading_disabled($user->id);
$showsubmit = ($submission || $teamsubmission) && $showlinks;
if ($teamsubmission && ($teamsubmission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED)) {
$showsubmit = false;
}
if ($submission && ($submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED)) {
$showsubmit = false;
}
$extensionduedate = null;
if ($grade) {
$extensionduedate = $grade->extensionduedate;
}
$viewfullnames = has_capability('moodle/site:viewfullnames', $this->get_course_context());
$o .= $this->output->render(new assign_submission_status($this->get_instance()->allowsubmissionsfromdate,
$this->get_instance()->alwaysshowdescription,
$submission,
$this->get_instance()->teamsubmission,
$teamsubmission,
$submissiongroup,
$notsubmitted,
$this->is_any_submission_plugin_enabled(),
$gradelocked,
$this->is_graded($user->id),
@ -2134,10 +2365,13 @@ class assign {
$this->get_return_action(),
$this->get_return_params(),
$this->get_course_module()->id,
$this->get_course()->id,
assign_submission_status::STUDENT_VIEW,
$showedit,
$showsubmit,
$extensionduedate));
$viewfullnames,
$extensionduedate,
$this->get_context()));
require_once($CFG->libdir.'/gradelib.php');
require_once($CFG->dirroot.'/grade/grading/lib.php');
@ -2213,16 +2447,31 @@ class assign {
$this->get_course_module()->id));
if ($this->can_grade()) {
$o .= $this->output->render(new assign_grading_summary($this->count_participants(0),
$this->get_instance()->submissiondrafts,
$this->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_DRAFT),
$this->is_any_submission_plugin_enabled(),
$this->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_SUBMITTED),
$this->get_instance()->cutoffdate,
$this->get_instance()->duedate,
$this->get_course_module()->id,
$this->count_submissions_need_grading()
));
if ($this->get_instance()->teamsubmission) {
$summary = new assign_grading_summary($this->count_teams(),
$this->get_instance()->submissiondrafts,
$this->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_DRAFT),
$this->is_any_submission_plugin_enabled(),
$this->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_SUBMITTED),
$this->get_instance()->cutoffdate,
$this->get_instance()->duedate,
$this->get_course_module()->id,
$this->count_submissions_need_grading(),
$this->get_instance()->teamsubmission);
$o .= $this->output->render($summary);
} else {
$summary = new assign_grading_summary($this->count_participants(0),
$this->get_instance()->submissiondrafts,
$this->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_DRAFT),
$this->is_any_submission_plugin_enabled(),
$this->count_submissions_with_status(ASSIGN_SUBMISSION_STATUS_SUBMITTED),
$this->get_instance()->cutoffdate,
$this->get_instance()->duedate,
$this->get_course_module()->id,
$this->count_submissions_need_grading(),
$this->get_instance()->teamsubmission);
$o .= $this->output->render($summary);
}
}
$grade = $this->get_user_grade($USER->id, false);
$submission = $this->get_user_submission($USER->id, false);
@ -2291,9 +2540,22 @@ class assign {
*/
private function gradebook_item_update($submission=NULL, $grade=NULL) {
if($submission != NULL){
if ($submission != NULL) {
if ($submission->userid == 0) {
// This is a group submission update.
$team = groups_get_members($submission->groupid, 'u.id');
foreach ($team as $member) {
$submission->groupid = 0;
$submission->userid = $member->id;
$this->gradebook_item_update($submission, null);
}
return;
}
$gradebookgrade = $this->convert_submission_for_gradebook($submission);
}else{
} else {
$gradebookgrade = $this->convert_grade_for_gradebook($grade);
}
// Grading is disabled, return.
@ -2307,15 +2569,80 @@ class assign {
}
/**
* update grades in the gradebook based on submission time
* update team submission
*
* @param stdClass $submission
* @param int $userid
* @param bool $updatetime
* @return bool
*/
private function update_submission(stdClass $submission, $updatetime=true) {
private function update_team_submission(stdClass $submission, $userid, $updatetime) {
global $DB;
if ($updatetime) {
$submission->timemodified = time();
}
// First update the submission for the current user.
$mysubmission = $this->get_user_submission($userid, true);
$mysubmission->status = $submission->status;
$this->update_submission($mysubmission, 0, $updatetime, false);
// Now check the team settings to see if this assignment qualifies as submitted or draft.
$team = $this->get_submission_group_members($submission->groupid, true);
$allsubmitted = true;
$anysubmitted = false;
foreach ($team as $member) {
$membersubmission = $this->get_user_submission($member->id, false);
if (!$membersubmission || $membersubmission->status != ASSIGN_SUBMISSION_STATUS_SUBMITTED) {
$allsubmitted = false;
if ($anysubmitted) {
break;
}
} else {
$anysubmitted = true;
}
}
if ($this->get_instance()->requireallteammemberssubmit) {
if ($allsubmitted) {
$submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
} else {
$submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
}
$result= $DB->update_record('assign_submission', $submission);
} else {
if ($anysubmitted) {
$submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
} else {
$submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
}
$result= $DB->update_record('assign_submission', $submission);
}
$this->gradebook_item_update($submission);
return $result;
}
/**
* update grades in the gradebook based on submission time
*
* @param stdClass $submission
* @param int $userid
* @param bool $updatetime
* @param bool $teamsubmission
* @return bool
*/
private function update_submission(stdClass $submission, $userid, $updatetime, $teamsubmission) {
global $DB;
if ($teamsubmission) {
return $this->update_team_submission($submission, $userid, $updatetime);
}
if ($updatetime) {
$submission->timemodified = time();
}
@ -2375,7 +2702,14 @@ class assign {
if (!is_enrolled($this->get_course_context(), $userid)) {
return false;
}
if ($submission = $this->get_user_submission($userid, false)) {
$submission = false;
if ($this->get_instance()->teamsubmission) {
$submission = $this->get_group_submission($USER->id, 0, false);
} else {
$submission = $this->get_user_submission($USER->id, false);
}
if ($submission) {
if ($this->get_instance()->submissiondrafts && $submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED) {
// drafts are tracked and the student has submitted the assignment
return false;
@ -2404,11 +2738,6 @@ class assign {
public function render_area_files($component, $area, $submissionid) {
global $USER;
if (!$submissionid) {
$submission = $this->get_user_submission($USER->id,false);
$submissionid = $submission->id;
}
$fs = get_file_storage();
$browser = get_file_browser();
$files = $fs->get_area_files($this->get_context()->id, $component, $area , $submissionid , "timemodified", false);
@ -2578,14 +2907,18 @@ class assign {
* @return void
*/
private function notify_student_submission_receipt(stdClass $submission) {
global $DB;
global $DB, $USER;
$adminconfig = $this->get_admin_config();
if (empty($adminconfig->submissionreceipts)) {
// No need to do anything
return;
}
$user = $DB->get_record('user', array('id'=>$submission->userid), '*', MUST_EXIST);
if ($submission->userid) {
$user = $DB->get_record('user', array('id'=>$submission->userid), '*', MUST_EXIST);
} else {
$user = $USER;
}
$this->send_notification($user, $user, 'submissionreceipt', 'assign_notification', $submission->timemodified);
}
@ -2596,7 +2929,7 @@ class assign {
* @return void
*/
private function notify_graders(stdClass $submission) {
global $DB;
global $DB, $USER;
$late = $this->get_instance()->duedate && ($this->get_instance()->duedate < time());
@ -2604,7 +2937,11 @@ class assign {
return;
}
$user = $DB->get_record('user', array('id'=>$submission->userid), '*', MUST_EXIST);
if ($submission->userid) {
$user = $DB->get_record('user', array('id'=>$submission->userid), '*', MUST_EXIST);
} else {
$user = $USER;
}
if ($teachers = $this->get_graders($user->id)) {
foreach ($teachers as $teacher) {
$this->send_notification($user, $teacher, 'gradersubmissionupdated', 'assign_notification', $submission->timemodified);
@ -2648,7 +2985,12 @@ class assign {
if ($mform->get_data() == false) {
return false;
}
$submission = $this->get_user_submission($USER->id,true);
if ($this->get_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();
@ -2657,7 +2999,7 @@ class assign {
}
$submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
$this->update_submission($submission);
$this->update_submission($submission, $USER->id, true, $this->get_instance()->teamsubmission);
$completion = new completion_info($this->get_course());
if ($completion->is_enabled($this->get_course_module()) && $this->get_instance()->completionsubmit) {
$completion->update_state($this->get_course_module(), COMPLETION_COMPLETE, $USER->id);
@ -2987,7 +3329,17 @@ class assign {
return true;
}
if ($data = $mform->get_data()) {
$submission = $this->get_user_submission($USER->id, true); //create the submission if needed & its id
if ($this->get_instance()->teamsubmission) {
$submission = $this->get_group_submission($USER->id, 0, true);
} else {
$submission = $this->get_user_submission($USER->id, true);
}
if ($this->get_instance()->submissiondrafts) {
$submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
} else {
$submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
}
$grade = $this->get_user_grade($USER->id, false); // get the grade to check if it is locked
if ($grade && $grade->locked) {
print_error('submissionslocked', 'assign');
@ -3003,7 +3355,7 @@ class assign {
}
}
$this->update_submission($submission);
$this->update_submission($submission, $USER->id, true, $this->get_instance()->teamsubmission);
// Logging
if (isset($data->submissionstatement)) {
@ -3189,13 +3541,18 @@ class assign {
$mform->addElement('hidden', 'ajax', optional_param('ajax', 0, PARAM_INT));
$mform->setType('ajax', PARAM_INT);
if ($this->get_instance()->teamsubmission) {
$mform->addElement('selectyesno', 'applytoall', get_string('applytoteam', 'assign'));
$mform->setDefault('applytoall', 1);
}
$mform->addElement('hidden', 'action', 'submitgrade');
$mform->setType('action', PARAM_ALPHA);
$buttonarray=array();
$buttonarray[] = $mform->createElement('submit', 'savegrade', get_string('savechanges', 'assign'));
if (!$last){
if (!$last) {
$buttonarray[] = $mform->createElement('submit', 'saveandshownext', get_string('savenext','assign'));
}
$buttonarray[] = $mform->createElement('cancel', 'cancelbutton', get_string('cancel'));
@ -3207,7 +3564,7 @@ class assign {
$buttonarray[] = $mform->createElement('submit', 'nosaveandprevious', get_string('previous','assign'));
}
if (!$last){
if (!$last) {
$buttonarray[] = $mform->createElement('submit', 'nosaveandnext', get_string('nosavebutnext', 'assign'));
}
$mform->addGroup($buttonarray, 'navar', '', array(' '), false);
@ -3282,9 +3639,14 @@ class assign {
public function add_submission_form_elements(MoodleQuickForm $mform, stdClass $data) {
global $USER;
$submission = $this->get_user_submission($USER->id, false);
// Team submissions.
if ($this->get_instance()->teamsubmission) {
$submission = $this->get_group_submission($USER->id, 0, false);
} else {
$submission = $this->get_user_submission($USER->id, false);
}
// submission statement
// Submission statement.
$adminconfig = $this->get_admin_config();
$requiresubmissionstatement = !empty($adminconfig->requiresubmissionstatement) ||
@ -3333,14 +3695,16 @@ class assign {
}
$submission = $this->get_user_submission($userid, false);
if (!$submission) {
return;
}
$submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
$this->update_submission($submission, false);
$this->update_submission($submission, $USER->id, true, $this->get_instance()->teamsubmission);
// update the modified time on the grade (grader modified)
// Update the modified time on the grade (grader modified).
$grade = $this->get_user_grade($userid, true);
$grade->grader = $USER->id;
$this->update_grade($grade);
$user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
@ -3407,6 +3771,55 @@ class assign {
$this->add_to_log('unlock submission', get_string('unlocksubmissionforstudent', 'assign', array('id'=>$user->id, 'fullname'=>fullname($user))));
}
/**
* Apply a grade from a grading form to a user (may be called multiple times for a group submission)
*
* @param stdClass $formdata - the data from the form
* @param int $userid - the user to apply the grade to
* @return void
*/
private function apply_grade_to_user($formdata, $userid) {
global $USER, $CFG, $DB;
$grade = $this->get_user_grade($userid, true);
$gradingdisabled = $this->grading_disabled($userid);
$gradinginstance = $this->get_grading_instance($userid, $gradingdisabled);
if (!$gradingdisabled) {
if ($gradinginstance) {
$grade->grade = $gradinginstance->submit_and_get_grade($formdata->advancedgrading, $grade->id);
} else {
// Handle the case when grade is set to No Grade.
if (isset($formdata->grade)) {
$grade->grade= grade_floatval(unformat_float($formdata->grade));
}
}
}
$grade->grader= $USER->id;
$adminconfig = $this->get_admin_config();
$gradebookplugin = $adminconfig->feedback_plugin_for_gradebook;
// Call save in plugins.
foreach ($this->feedbackplugins as $plugin) {
if ($plugin->is_enabled() && $plugin->is_visible()) {
if (!$plugin->save($grade, $formdata)) {
$result = false;
print_error($plugin->get_error());
}
if (('assignfeedback_' . $plugin->get_type()) == $gradebookplugin) {
// This is the feedback plugin chose to push comments to the gradebook.
$grade->feedbacktext = $plugin->text_for_gradebook($grade);
$grade->feedbackformat = $plugin->format_for_gradebook($grade);
}
}
}
$this->update_grade($grade);
$user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
$this->add_to_log('grade submission', $this->format_grade_for_log($grade));
}
/**
* save outcomes submitted from grading form
*
@ -3454,7 +3867,7 @@ class assign {
* @return bool - was the grade saved
*/
private function process_save_grade(&$mform) {
global $USER, $DB, $CFG;
global $CFG;
// Include grade form
require_once($CFG->dirroot . '/mod/assign/gradeform.php');
@ -3479,49 +3892,22 @@ class assign {
$mform = new mod_assign_grade_form(null, array($this, $data, array('rownum'=>$rownum, 'useridlist'=>$useridlist, 'last'=>false)), 'post', '', array('class'=>'gradeform'));
if ($formdata = $mform->get_data()) {
$grade = $this->get_user_grade($userid, true);
$gradingdisabled = $this->grading_disabled($userid);
$gradinginstance = $this->get_grading_instance($userid, $gradingdisabled);
if (!$gradingdisabled) {
if ($gradinginstance) {
$grade->grade = $gradinginstance->submit_and_get_grade($formdata->advancedgrading, $grade->id);
} else {
// handle the case when grade is set to No Grade
if (isset($formdata->grade)) {
$grade->grade = grade_floatval(unformat_float($formdata->grade));
if ($this->get_instance()->teamsubmission && $formdata->applytoall) {
$groupid = 0;
if ($this->get_submission_group($userid)) {
$group = $this->get_submission_group($userid);
if ($group) {
$groupid = $group->id;
}
}
}
$grade->grader= $USER->id;
$adminconfig = $this->get_admin_config();
$gradebookplugin = $adminconfig->feedback_plugin_for_gradebook;
// call save in plugins
foreach ($this->feedbackplugins as $plugin) {
if ($plugin->is_enabled() && $plugin->is_visible()) {
if (!$plugin->save($grade, $formdata)) {
$result = false;
print_error($plugin->get_error());
}
if (('assignfeedback_' . $plugin->get_type()) == $gradebookplugin) {
// this is the feedback plugin chose to push comments to the gradebook
$grade->feedbacktext = $plugin->text_for_gradebook($grade);
$grade->feedbackformat = $plugin->format_for_gradebook($grade);
}
$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);
}
} else {
$this->apply_grade_to_user($formdata, $userid);
}
$this->process_outcomes($userid, $formdata);
$grade->mailed = 0;
$this->update_grade($grade);
$user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
$this->add_to_log('grade submission', $this->format_grade_for_log($grade));
} else {
return false;
}

View File

@ -107,6 +107,26 @@ class mod_assign_mod_form extends moodleform_mod {
$mform->addHelpButton('sendlatenotifications', 'sendlatenotifications', 'assign');
$mform->setDefault('sendlatenotifications', 1);
$mform->disabledIf('sendlatenotifications', 'sendnotifications', 'eq', 1);
$mform->addElement('selectyesno', 'teamsubmission', get_string('teamsubmission', 'assign'));
$mform->addHelpButton('teamsubmission', 'teamsubmission', 'assign');
$mform->setDefault('teamsubmission', 0);
$mform->addElement('selectyesno', 'requireallteammemberssubmit', get_string('requireallteammemberssubmit', 'assign'));
$mform->addHelpButton('requireallteammemberssubmit', 'requireallteammemberssubmit', 'assign');
$mform->setDefault('requireallteammemberssubmit', 0);
$mform->disabledIf('requireallteammemberssubmit', 'teamsubmission', 'eq', 0);
$mform->disabledIf('requireallteammemberssubmit', 'submissiondrafts', 'eq', 0);
$groupings = groups_get_all_groupings($assignment->get_course()->id);
$options = array();
$options[0] = get_string('none');
foreach ($groupings as $grouping) {
$options[$grouping->id] = $grouping->name;
}
$mform->addElement('select', 'teamsubmissiongroupingid', get_string('teamsubmissiongroupingid', 'assign'), $options);
$mform->addHelpButton('teamsubmissiongroupingid', 'teamsubmissiongroupingid', 'assign');
$mform->setDefault('teamsubmissiongroupingid', 0);
$mform->disabledIf('teamsubmissiongroupingid', 'teamsubmission', 'eq', 0);
// plagiarism enabling form
if (!empty($CFG->enableplagiarism)) {

View File

@ -289,6 +289,14 @@ class assign_submission_status implements renderable {
var $alwaysshowdescription = false;
/** @var stdClass the submission info (may be null) */
var $submission = null;
/** @var boolean teamsubmissionenabled - true or false */
public $teamsubmissionenabled = false;
/** @var stdClass teamsubmission the team submission info (may be null) */
public $teamsubmission = null;
/** @var stdClass submissiongroup the submission group info (may be null) */
public $submissiongroup = null;
/** @var array submissiongroupmemberswhoneedtosubmit list of users who still need to submit */
public $submissiongroupmemberswhoneedtosubmit = array();
/** @var bool submissionsenabled */
var $submissionsenabled = false;
/** @var bool locked */
@ -305,16 +313,22 @@ class assign_submission_status implements renderable {
var $returnaction = '';
/** @var string returnparams */
var $returnparams = array();
/** @var int courseid */
public $courseid = 0;
/** @var int coursemoduleid */
var $coursemoduleid = 0;
/** @var int the view (assign_submission_status::STUDENT_VIEW OR assign_submission_status::GRADER_VIEW) */
var $view = self::STUDENT_VIEW;
/** @var bool canviewfullnames */
public $canviewfullnames = false;
/** @var bool canedit */
var $canedit = false;
/** @var bool cansubmit */
var $cansubmit = false;
/** @var int extensionduedate */
public $extensionduedate = 0;
/** @var context context */
public $context = 0;
/**
* constructor
@ -322,6 +336,10 @@ class assign_submission_status implements renderable {
* @param int $allowsubmissionsfromdate
* @param bool $alwaysshowdescription
* @param stdClass $submission
* @param bool $teamsubmissionenabled
* @param stdClass $teamsubmission
* @param int $submissiongroup
* @param array $submissiongroupmemberswhoneedtosubmit
* @param bool $submissionsenabled
* @param bool $locked
* @param bool $graded
@ -331,17 +349,27 @@ class assign_submission_status implements renderable {
* @param string $returnaction
* @param array $returnparams
* @param int $coursemoduleid
* @param int $courseid
* @param string $view
* @param bool $canedit
* @param bool $cansubmit
* @param bool $canviewfullnames
* @param int $extensionduedate - Any extension to the due date granted for this user
* @param context $context - Any extension to the due date granted for this user
*/
public function __construct($allowsubmissionsfromdate, $alwaysshowdescription, $submission, $submissionsenabled,
public function __construct($allowsubmissionsfromdate, $alwaysshowdescription, $submission,
$teamsubmissionenabled, $teamsubmission, $submissiongroup,
$submissiongroupmemberswhoneedtosubmit, $submissionsenabled,
$locked, $graded, $duedate, $cutoffdate, $submissionplugins, $returnaction, $returnparams,
$coursemoduleid, $view, $canedit, $cansubmit, $extensionduedate) {
$coursemoduleid, $courseid, $view, $canedit, $cansubmit, $canviewfullnames, $extensionduedate,
$context) {
$this->allowsubmissionsfromdate = $allowsubmissionsfromdate;
$this->alwaysshowdescription = $alwaysshowdescription;
$this->submission = $submission;
$this->teamsubmissionenabled = $teamsubmissionenabled;
$this->teamsubmission = $teamsubmission;
$this->submissiongroup = $submissiongroup;
$this->submissiongroupmemberswhoneedtosubmit = $submissiongroupmemberswhoneedtosubmit;
$this->submissionsenabled = $submissionsenabled;
$this->locked = $locked;
$this->graded = $graded;
@ -351,10 +379,13 @@ class assign_submission_status implements renderable {
$this->returnaction = $returnaction;
$this->returnparams = $returnparams;
$this->coursemoduleid = $coursemoduleid;
$this->courseid = $courseid;
$this->view = $view;
$this->canedit = $canedit;
$this->cansubmit = $cansubmit;
$this->canviewfullnames = $canviewfullnames;
$this->extensionduedate = $extensionduedate;
$this->context = $context;
}
}
@ -424,6 +455,8 @@ class assign_grading_summary implements renderable {
var $cutoffdate = 0;
/** @var int coursemoduleid - The assignment course module id */
var $coursemoduleid = 0;
/** @var boolean teamsubmission - Are team submissions enabled for this assignment */
public $teamsubmission = false;
/**
* constructor
@ -437,10 +470,12 @@ class assign_grading_summary implements renderable {
* @param int $duedate
* @param int $coursemoduleid
* @param int $submissionsneedgradingcount
* @param bool $teamsubmission
*/
public function __construct($participantcount, $submissiondraftsenabled, $submissiondraftscount,
$submissionsenabled, $submissionssubmittedcount,
$cutoffdate, $duedate, $coursemoduleid, $submissionsneedgradingcount) {
public function __construct($participantcount, $submissiondraftsenabled,
$submissiondraftscount, $submissionsenabled,
$submissionssubmittedcount, $cutoffdate, $duedate,
$coursemoduleid, $submissionsneedgradingcount, $teamsubmission) {
$this->participantcount = $participantcount;
$this->submissiondraftsenabled = $submissiondraftsenabled;
$this->submissiondraftscount = $submissiondraftscount;
@ -450,6 +485,7 @@ class assign_grading_summary implements renderable {
$this->cutoffdate = $cutoffdate;
$this->coursemoduleid = $coursemoduleid;
$this->submissionsneedgradingcount = $submissionsneedgradingcount;
$this->teamsubmission = $teamsubmission;
}
}

View File

@ -232,8 +232,13 @@ class mod_assign_renderer extends plugin_renderer_base {
$t = new html_table();
// status
$this->add_table_row_tuple($t, get_string('numberofparticipants', 'assign'),
$summary->participantcount);
if ($summary->teamsubmission) {
$this->add_table_row_tuple($t, get_string('numberofteams', 'assign'),
$summary->participantcount);
} else {
$this->add_table_row_tuple($t, get_string('numberofparticipants', 'assign'),
$summary->participantcount);
}
// drafts
if ($summary->submissiondraftsenabled) {
@ -378,20 +383,68 @@ class mod_assign_renderer extends plugin_renderer_base {
$t = new html_table();
if ($status->teamsubmissionenabled) {
$row = new html_table_row();
$cell1 = new html_table_cell(get_string('submissionteam', 'assign'));
$group = $status->submissiongroup;
if ($group) {
$cell2 = new html_table_cell(format_string($group->name, false, $status->context));
} else {
$cell2 = new html_table_cell(get_string('defaultteam', 'assign'));
}
$row->cells = array($cell1, $cell2);
$t->data[] = $row;
}
$row = new html_table_row();
$cell1 = new html_table_cell(get_string('submissionstatus', 'assign'));
if ($status->submission) {
$cell2 = new html_table_cell(get_string('submissionstatus_' . $status->submission->status, 'assign'));
$cell2->attributes = array('class'=>'submissionstatus' . $status->submission->status);
if (!$status->teamsubmissionenabled) {
if ($status->submission) {
$cell2 = new html_table_cell(get_string('submissionstatus_' . $status->submission->status, 'assign'));
$cell2->attributes = array('class'=>'submissionstatus' . $status->submission->status);
} else {
if (!$status->submissionsenabled) {
$cell2 = new html_table_cell(get_string('noonlinesubmissions', 'assign'));
} else {
$cell2 = new html_table_cell(get_string('nosubmission', 'assign'));
}
}
$row->cells = array($cell1, $cell2);
$t->data[] = $row;
} else {
if (!$status->submissionsenabled) {
$cell2 = new html_table_cell(get_string('noonlinesubmissions', 'assign'));
$row = new html_table_row();
$cell1 = new html_table_cell(get_string('submissionstatus', 'assign'));
if ($status->teamsubmission) {
$submissionsummary = get_string('submissionstatus_' . $status->teamsubmission->status, 'assign');
$groupid = 0;
if ($status->submissiongroup) {
$groupid = $status->submissiongroup->id;
}
$members = $status->submissiongroupmemberswhoneedtosubmit;
$userslist = array();
foreach ($members as $member) {
$url = new moodle_url('/user/view.php', array('id' => $member->id, 'course'=>$status->courseid));
$userslist[] = $this->output->action_link($url, fullname($member, $status->canviewfullnames));
}
if (count($userslist) > 0) {
$userstr = join(', ', $userslist);
$submissionsummary .= $this->output->container(get_string('userswhoneedtosubmit', 'assign', $userstr));
}
$cell2 = new html_table_cell($submissionsummary);
$cell2->attributes = array('class'=>'submissionstatus' . $status->teamsubmission->status);
} else {
$cell2 = new html_table_cell(get_string('nosubmission', 'assign'));
if (!$status->submissionsenabled) {
$cell2 = new html_table_cell(get_string('noonlinesubmissions', 'assign'));
} else {
$cell2 = new html_table_cell(get_string('nosubmission', 'assign'));
}
}
$row->cells = array($cell1, $cell2);
$t->data[] = $row;
}
$row->cells = array($cell1, $cell2);
$t->data[] = $row;
// status
if ($status->locked) {
@ -488,19 +541,20 @@ class mod_assign_renderer extends plugin_renderer_base {
}
// Last modified.
if ($status->submission) {
$submission = $status->teamsubmission ? $status->teamsubmission : $status->submission;
if ($submission) {
$row = new html_table_row();
$cell1 = new html_table_cell(get_string('timemodified', 'assign'));
$cell2 = new html_table_cell(userdate($status->submission->timemodified));
$cell2 = new html_table_cell(userdate($submission->timemodified));
$row->cells = array($cell1, $cell2);
$t->data[] = $row;
foreach ($status->submissionplugins as $plugin) {
if ($plugin->is_enabled() && $plugin->is_visible() && !$plugin->is_empty($status->submission)) {
if ($plugin->is_enabled() && $plugin->is_visible() && !$plugin->is_empty($submission)) {
$row = new html_table_row();
$cell1 = new html_table_cell($plugin->get_name());
$pluginsubmission = new assign_submission_plugin_submission($plugin,
$status->submission,
$submission,
assign_submission_plugin_submission::SUMMARY,
$status->coursemoduleid,
$status->returnaction,
@ -519,7 +573,7 @@ class mod_assign_renderer extends plugin_renderer_base {
// Links.
if ($status->view == assign_submission_status::STUDENT_VIEW) {
if ($status->canedit) {
if (!$status->submission) {
if (!$submission) {
$urlparams = array('id' => $status->coursemoduleid, 'action' => 'editsubmission');
$o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams),
get_string('addsubmission', 'assign'), 'get');

View File

@ -25,7 +25,7 @@
defined('MOODLE_INTERNAL') || die();
$module->component = 'mod_assign'; // Full name of the plugin (used for diagnostics)
$module->version = 2012082100; // The current module version (Date: YYYYMMDDXX)
$module->version = 2012082300; // The current module version (Date: YYYYMMDDXX)
$module->requires = 2012061700; // Requires this Moodle version
$module->cron = 60;