Skip to content
Browse files

MDL-31295: Allow granting individual extension dates to students for …

…mod_assign
  • Loading branch information...
1 parent 21a87e5 commit 9e795179ad2574c0e06b8f1763372abb6debaa60 Damyon Wiese committed Jun 8, 2012
View
5 mod/assign/backup/moodle2/backup_assign_stepslib.php
@@ -48,11 +48,11 @@ protected function define_structure() {
'intro',
'introformat',
'alwaysshowdescription',
- 'preventlatesubmissions',
'submissiondrafts',
'sendnotifications',
'sendlatenotifications',
'duedate',
+ 'cutoffdate',
'allowsubmissionsfromdate',
'grade',
'timemodified',
@@ -75,7 +75,8 @@ protected function define_structure() {
'grader',
'grade',
'locked',
- 'mailed'));
+ 'mailed',
+ 'extensionduedate'));
$pluginconfigs = new backup_nested_element('plugin_configs');
View
11 mod/assign/backup/moodle2/restore_assign_stepslib.php
@@ -74,6 +74,16 @@ protected function process_assign($data) {
$data->allowsubmissionsfromdate = $this->apply_date_offset($data->allowsubmissionsfromdate);
$data->duedate = $this->apply_date_offset($data->duedate);
+ if (!isset($data->cutoffdate)) {
+ $data->cutoffdate = 0;
+ }
+
+ if (!empty($data->preventlatesubmissions)) {
+ $data->cutoffdate = $data->duedate;
+ } else {
+ $data->cutoffdate = $this->apply_date_offset($data->cutoffdate);
+ }
+
$newitemid = $DB->insert_record('assign', $data);
@@ -121,6 +131,7 @@ protected function process_assign_grade($data) {
$data->timecreated = $this->apply_date_offset($data->timecreated);
$data->userid = $this->get_mappingid('user', $data->userid);
$data->grader = $this->get_mappingid('user', $data->grader);
+ $data->extensionduedate = $this->apply_date_offset($data->extensionduedate);
$newitemid = $DB->insert_record('assign_grades', $data);
View
12 mod/assign/db/access.php
@@ -81,6 +81,18 @@
),
'clonepermissionsfrom' => 'moodle/course:manageactivities'
),
+
+ 'mod/assign:grantextension' => array(
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_MODULE,
+ 'archetypes' => array(
+ 'teacher' => CAP_ALLOW,
+ 'editingteacher' => CAP_ALLOW,
+ 'manager' => CAP_ALLOW
+ ),
+ 'clonepermissionsfrom' => 'gradereport/grader:view'
+ ),
+
);
View
15 mod/assign/db/install.xml 100644 → 100755
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/assign/db" VERSION="20120423" COMMENT="XMLDB file for Moodle mod/assign"
+<XMLDB PATH="mod/assign/db" VERSION="20120830" COMMENT="XMLDB file for Moodle mod/assign"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
@@ -12,17 +12,17 @@
<FIELD NAME="intro" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="The description of the assignment. This field is used by feature MOD_INTRO." PREVIOUS="name" NEXT="introformat"/>
<FIELD NAME="introformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The format of the description field of the assignment. This field is used by feature MOD_INTRO." PREVIOUS="intro" NEXT="alwaysshowdescription"/>
<FIELD NAME="alwaysshowdescription" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If false the assignment intro will only be displayed after the allowsubmissionsfrom date. If true it will always be displayed." PREVIOUS="introformat" NEXT="nosubmissions"/>
- <FIELD NAME="nosubmissions" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="This field is a cache for is_any_submission_plugin_enabled() which allows Moodle pages to distinguish offline assignment types without loading the assignment class." PREVIOUS="alwaysshowdescription" NEXT="preventlatesubmissions"/>
- <FIELD NAME="preventlatesubmissions" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If true, submissions will not be accepted past the due date." PREVIOUS="nosubmissions" NEXT="submissiondrafts"/>
- <FIELD NAME="submissiondrafts" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If true, assignment submissions will be considered drafts until the student clicks on the submit assignmnet button." PREVIOUS="preventlatesubmissions" NEXT="sendnotifications"/>
+ <FIELD NAME="nosubmissions" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="This field is a cache for is_any_submission_plugin_enabled() which allows Moodle pages to distinguish offline assignment types without loading the assignment class." PREVIOUS="alwaysshowdescription" NEXT="submissiondrafts"/>
+ <FIELD NAME="submissiondrafts" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If true, assignment submissions will be considered drafts until the student clicks on the submit assignmnet button." PREVIOUS="nosubmissions" NEXT="sendnotifications"/>
<FIELD NAME="sendnotifications" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Allows the disabling of email notifications in the assign module." PREVIOUS="submissiondrafts" NEXT="sendlatenotifications"/>
<FIELD NAME="sendlatenotifications" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Allows separate enabling of notifications for late assignment submissions." PREVIOUS="sendnotifications" NEXT="duedate"/>
<FIELD NAME="duedate" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The due date for the assignment. Displayed to students." PREVIOUS="sendlatenotifications" NEXT="allowsubmissionsfromdate"/>
<FIELD NAME="allowsubmissionsfromdate" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If set, submissions will only be accepted after this date." PREVIOUS="duedate" NEXT="grade"/>
<FIELD NAME="grade" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="The maximum grade for this assignment. Can be negative to indicate the use of a scale." PREVIOUS="allowsubmissionsfromdate" NEXT="timemodified"/>
<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"/>
+ <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"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="The unique id for this assignment instance."/>
@@ -58,7 +58,8 @@
<FIELD NAME="grader" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="timemodified" NEXT="grade"/>
<FIELD NAME="grade" TYPE="number" LENGTH="10" NOTNULL="false" DEFAULT="0" SEQUENCE="false" DECIMALS="5" COMMENT="The numerical grade for this assignment submission. Can be determined by scales/advancedgradingforms etc but will always be converted back to a floating point number." PREVIOUS="grader" NEXT="locked"/>
<FIELD NAME="locked" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="A flag to prevent changes for a single student submission." PREVIOUS="grade" NEXT="mailed"/>
- <FIELD NAME="mailed" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="locked"/>
+ <FIELD NAME="mailed" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Has the student been sent a notification about this grade update?" PREVIOUS="locked" NEXT="extensionduedate"/>
+ <FIELD NAME="extensionduedate" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="An extension date assigned to an individual student" PREVIOUS="mailed"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="The unique id for this grade." NEXT="assignment"/>
@@ -89,4 +90,4 @@
</INDEXES>
</TABLE>
</TABLES>
-</XMLDB>
+</XMLDB>
View
39 mod/assign/db/upgrade.php
@@ -80,6 +80,45 @@ function xmldb_assign_upgrade($oldversion) {
upgrade_mod_savepoint(true, 2012081600, 'assign');
}
+ // Individual extension dates support.
+ if ($oldversion < 2012082100) {
+
+ // Define field sendlatenotifications to be added to assign.
+ $table = new xmldb_table('assign');
+ $field = new xmldb_field('cutoffdate', XMLDB_TYPE_INTEGER, '10', null,
+ XMLDB_NOTNULL, null, '0', 'completionsubmit');
+
+ // Conditionally launch add field sendlatenotifications.
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+ // If prevent late is on - set cutoffdate to due date.
+
+ // Now remove the preventlatesubmissions column.
+ $field = new xmldb_field('preventlatesubmissions', XMLDB_TYPE_INTEGER, '2', null,
+ XMLDB_NOTNULL, null, '0', 'nosubmissions');
+ if ($dbman->field_exists($table, $field)) {
+ // Set the cutoffdate to the duedate if preventlatesubmissions was enabled.
+ $sql = 'UPDATE {assign} SET cutoffdate = duedate WHERE preventlatesubmissions = 1';
+ $DB->execute($sql);
+
+ $dbman->drop_field($table, $field);
+ }
+
+ // Define field extensionduedate to be added to assign_grades
+ $table = new xmldb_table('assign_grades');
+ $field = new xmldb_field('extensionduedate', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'mailed');
+
+ // Conditionally launch add field extensionduedate
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ // Assign savepoint reached.
+ upgrade_mod_savepoint(true, 2012082100, 'assign');
+ }
+
+
return true;
}
View
102 mod/assign/extensionform.php
@@ -0,0 +1,102 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This file contains the forms to create and edit an instance of this module
+ *
+ * @package mod_assign
+ * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.');
+
+
+require_once($CFG->libdir.'/formslib.php');
+require_once($CFG->dirroot . '/mod/assign/locallib.php');
+
+/**
+ * Assignment extension dates form
+ *
+ * @package mod_assign
+ * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class mod_assign_extension_form extends moodleform {
+ /** @var array $instance - The data passed to this form */
+ private $instance;
+
+ /**
+ * Define the form - called by parent constructor
+ */
+ public function definition() {
+ $mform = $this->_form;
+
+ list($coursemoduleid, $userid, $batchusers, $instance, $data) = $this->_customdata;
+ // Instance variable is used by the form validation function.
+ $this->instance = $instance;
+
+ if ($batchusers) {
+ $listusersmessage = get_string('grantextensionforusers', 'assign', count(explode(',', $batchusers)));
+ $mform->addElement('static', 'applytoselectedusers', '', $listusersmessage);
+ }
+ if ($instance->allowsubmissionsfromdate) {
+ $mform->addElement('static', 'allowsubmissionsfromdate', get_string('allowsubmissionsfromdate', 'assign'),
+ userdate($instance->allowsubmissionsfromdate));
+ }
+ if ($instance->duedate) {
+ $mform->addElement('static', 'duedate', get_string('duedate', 'assign'), userdate($instance->duedate));
+ $finaldate = $instance->duedate;
+ }
+ if ($instance->cutoffdate) {
+ $mform->addElement('static', 'cutoffdate', get_string('cutoffdate', 'assign'), userdate($instance->cutoffdate));
+ $finaldate = $instance->cutoffdate;
+ }
+ $mform->addElement('date_time_selector', 'extensionduedate',
+ get_string('extensionduedate', 'assign'), array('optional'=>true));
+ $mform->setDefault('extensionduedate', $finaldate);
+ $mform->addElement('hidden', 'id', $coursemoduleid);
+ $mform->addElement('hidden', 'userid', $userid);
+ $mform->addElement('hidden', 'selectedusers', $batchusers);
+ $mform->addElement('hidden', 'action', 'saveextension');
+ $this->add_action_buttons(true, get_string('savechanges', 'assign'));
+
+ if ($data) {
+ $this->set_data($data);
+ }
+ }
+
+ /**
+ * Perform validation on the extension form
+ * @param array $data
+ * @param array $files
+ */
+ public function validation($data, $files) {
+ $errors = parent::validation($data, $files);
+ if ($this->instance->duedate && $data['extensionduedate']) {
+ if ($this->instance->duedate > $data['extensionduedate']) {
+ $errors['extensionduedate'] = get_string('extensionnotafterduedate', 'assign');
+ }
+ }
+ if ($this->instance->allowsubmissionsfromdate && $data['extensionduedate']) {
+ if ($this->instance->allowsubmissionsfromdate > $data['extensionduedate']) {
+ $errors['extensionduedate'] = get_string('extensionnotafterfromdate', 'assign');
+ }
+ }
+
+ return $errors;
+ }
+}
View
1 mod/assign/feedback/file/lang/en/assignfeedback_file.php
@@ -23,6 +23,7 @@
*/
$string['configmaxbytes'] = 'Maximum file size';
+$string['countfiles'] = '{$a} files';
$string['default'] = 'Enabled by default';
$string['default_help'] = 'If set, this feedback method will be enabled by default for all new assignments.';
$string['enabled'] = 'File feedback';
View
3 mod/assign/gradingbatchoperationsform.php
@@ -52,6 +52,9 @@ function definition() {
if ($instance['submissiondrafts']) {
$options['reverttodraft'] = get_string('reverttodraft', 'assign');
}
+ if ($instance['duedate']) {
+ $options['grantextension'] = get_string('grantextension', 'assign');
+ }
$mform->addElement('hidden', 'action', 'batchgradingoperation');
$mform->addElement('hidden', 'id', $instance['cm']);
$mform->addElement('hidden', 'selectedusers', '', array('class'=>'selectedusers'));
View
84 mod/assign/gradingtable.php
@@ -50,6 +50,8 @@ class assign_grading_table extends table_sql implements renderable {
private $tablemaxrows = 10000;
/** @var boolean $quickgrading */
private $quickgrading = false;
+ /** @var boolean $hasgrantextension - Only do the capability check once for the entire table */
+ private $hasgrantextension = false;
/**
* overridden constructor keeps a reference to the assignment class that is displaying this table
@@ -88,9 +90,19 @@ function __construct(assign $assignment, $perpage, $filter, $rowoffset, $quickgr
$params['assignmentid1'] = (int)$this->assignment->get_instance()->id;
$params['assignmentid2'] = (int)$this->assignment->get_instance()->id;
- $fields = user_picture::fields('u') . ', u.id as userid, ';
- $fields .= 's.status as status, s.id as submissionid, s.timecreated as firstsubmission, s.timemodified as timesubmitted, ';
- $fields .= 'g.id as gradeid, g.grade as grade, g.timemodified as timemarked, g.timecreated as firstmarked, g.mailed as mailed, g.locked as locked';
+ $fields = user_picture::fields('u') . ', ';
+ $fields .= 'u.id as userid, ';
+ $fields .= 's.status as status, ';
+ $fields .= 's.id as submissionid, ';
+ $fields .= 's.timecreated as firstsubmission, ';
+ $fields .= 's.timemodified as timesubmitted, ';
+ $fields .= 'g.id as gradeid, ';
+ $fields .= 'g.grade as grade, ';
+ $fields .= 'g.timemodified as timemarked, ';
+ $fields .= 'g.timecreated as firstmarked, ';
+ $fields .= 'g.mailed as mailed, ';
+ $fields .= 'g.locked as locked, ';
+ $fields .= 'g.extensionduedate as extensionduedate';
$from = '{user} u LEFT JOIN {assign_submission} s ON u.id = s.userid AND s.assignment = :assignmentid1' .
' LEFT JOIN {assign_grades} g ON u.id = g.userid AND g.assignment = :assignmentid2';
@@ -177,6 +189,7 @@ function __construct(assign $assignment, $perpage, $filter, $rowoffset, $quickgr
// load the grading info for all users
$this->gradinginfo = grade_get_grades($this->assignment->get_course()->id, 'mod', 'assign', $this->assignment->get_instance()->id, $users);
+ $this->hasgrantextension = has_capability('mod/assign:grantextension', $this->assignment->get_context());
if (!empty($CFG->enableoutcomes) && !empty($this->gradinginfo->outcomes)) {
$columns[] = 'outcomes';
@@ -409,16 +422,34 @@ function col_status(stdClass $row) {
if ($this->assignment->is_any_submission_plugin_enabled()) {
- $o .= $this->output->container(get_string('submissionstatus_' . $row->status, 'assign'), array('class'=>'submissionstatus' .$row->status));
+ $o .= $this->output->container(get_string('submissionstatus_' . $row->status, 'assign'),
+ array('class'=>'submissionstatus' .$row->status));
if ($this->assignment->get_instance()->duedate && $row->timesubmitted > $this->assignment->get_instance()->duedate) {
- $o .= $this->output->container(get_string('submittedlateshort', 'assign', format_time($row->timesubmitted - $this->assignment->get_instance()->duedate)), 'latesubmission');
+ if (!$row->extensionduedate || $row->timesubmitted > $row->extensionduedate) {
+ $latemessage = get_string('submittedlateshort', 'assign',
+ format_time($row->timesubmitted - $this->assignment->get_instance()->duedate));
+ $o .= $this->output->container($latemessage, 'latesubmission');
+ }
}
if ($row->locked) {
$o .= $this->output->container(get_string('submissionslockedshort', 'assign'), 'lockedsubmission');
}
if ($row->grade !== NULL && $row->grade >= 0) {
$o .= $this->output->container(get_string('graded', 'assign'), 'submissiongraded');
}
+ if (!$row->timesubmitted) {
+ $now = time();
+ $due = $this->assignment->get_instance()->duedate;
+ if ($row->extensionduedate) {
+ $due = $row->extensionduedate;
+ }
+ if ($due && ($now > $due)) {
+ $o .= $this->output->container(get_string('overdue', 'assign', format_time($now - $due)), 'overduesubmission');
+ }
+ }
+ if ($row->extensionduedate) {
+ $o .= $this->output->container(get_string('userextensiondate', 'assign', userdate($row->extensionduedate)), 'extensiondate');
+ }
}
return $o;
@@ -450,23 +481,42 @@ function col_edit(stdClass $row) {
}
$actions[$url->out(false)] = $description;
- if (!$row->status || $row->status == ASSIGN_SUBMISSION_STATUS_DRAFT || !$this->assignment->get_instance()->submissiondrafts) {
- if (!$row->locked) {
- $url = new moodle_url('/mod/assign/view.php', array('id' => $this->assignment->get_course_module()->id,
- 'userid'=>$row->id,
- 'action'=>'lock',
- 'sesskey'=>sesskey(),
- 'page'=>$this->currpage));
- $description = get_string('preventsubmissionsshort', 'assign');
- $actions[$url->out(false)] = $description;
- } else {
+ // Hide for offline assignments.
+ if ($this->assignment->is_any_submission_plugin_enabled()) {
+ if (!$row->status ||
+ $row->status == ASSIGN_SUBMISSION_STATUS_DRAFT ||
+ !$this->assignment->get_instance()->submissiondrafts) {
+
+ if (!$row->locked) {
+ $url = new moodle_url('/mod/assign/view.php', array('id' => $this->assignment->get_course_module()->id,
+ 'userid'=>$row->id,
+ 'action'=>'lock',
+ 'sesskey'=>sesskey(),
+ 'page'=>$this->currpage));
+ $description = get_string('preventsubmissionsshort', 'assign');
+ $actions[$url->out(false)] = $description;
+ } else {
+ $url = new moodle_url('/mod/assign/view.php', array('id' => $this->assignment->get_course_module()->id,
+ 'userid'=>$row->id,
+ 'action'=>'unlock',
+ 'sesskey'=>sesskey(),
+ 'page'=>$this->currpage));
+ $description = get_string('allowsubmissionsshort', 'assign');
+ $actions[$url->out(false)] = $description;
+ }
+ }
+
+ if (($this->assignment->get_instance()->duedate ||
+ $this->assignment->get_instance()->cutoffdate) &&
+ $this->hasgrantextension) {
$url = new moodle_url('/mod/assign/view.php', array('id' => $this->assignment->get_course_module()->id,
'userid'=>$row->id,
- 'action'=>'unlock',
+ 'action'=>'grantextension',
'sesskey'=>sesskey(),
'page'=>$this->currpage));
- $description = get_string('allowsubmissionsshort', 'assign');
+ $description = get_string('grantextension', 'assign');
$actions[$url->out(false)] = $description;
+
}
}
if ($row->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED && $this->assignment->get_instance()->submissiondrafts) {
View
24 mod/assign/lang/en/assign.php
@@ -35,6 +35,7 @@
$string['assign:addinstance'] = 'Add a new assignment';
$string['assign:exportownsubmission'] = 'Export own submission';
$string['assign:grade'] = 'Grade assignment';
+$string['assign:grantextension'] = 'Grant extension';
$string['assign:submit'] = 'Submit assignment';
$string['assign:view'] = 'View assignment';
$string['assignfeedback'] = 'Feedback plugin';
@@ -60,6 +61,7 @@
$string['backtoassignment'] = 'Back to assignment';
$string['batchoperationsdescription'] = 'With selected...';
$string['batchoperationconfirmlock'] = 'Lock all selected submissions?';
+$string['batchoperationconfirmgrantextension'] = 'Grant an extension to all selected submissions?';
$string['batchoperationconfirmunlock'] = 'Unlock all selected submissions?';
$string['batchoperationconfirmreverttodraft'] = 'Revert selected submissions to draft?';
$string['batchoperationlock'] = 'lock submissions';
@@ -78,6 +80,10 @@
$string['couldnotcreatenewassignmentinstance'] = 'Could not create new assignment instance.';
$string['couldnotfindassignmenttoupgrade'] = 'Could not find old assignment instance to upgrade.';
$string['currentgrade'] = 'Current grade in gradebook';
+$string['cutoffdate'] = 'Cut-off date';
+$string['cutoffdate_help'] = 'If set, the assignment will not accept submissions after this date without an extension.';
+$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['deletepluginareyousure'] = 'Delete assignment plugin {$a}: are you sure?';
@@ -87,12 +93,15 @@
$string['downloadall'] = 'Download all submissions';
$string['download all submissions'] = 'Download all submissions in a zip file.';
$string['duedate'] = 'Due date';
-$string['duedate_help'] = 'This is when the assignment is due. If late submissions are allowed, any assignments submitted after this date are marked as late.';
+$string['duedate_help'] = 'This is when the assignment is due. Submissions will still be allowed after this date but any assignments submitted after this date are marked as late. To prevent submissions after a certain date - set the assignment cut off date.';
$string['duedateno'] = 'No due date';
$string['duedatereached'] = 'The due date for this assignment has now passed';
$string['duedatevalidation'] = 'Due date must be after the allow submissions from date.';
$string['editsubmission'] = 'Edit my submission';
$string['editaction'] = 'Actions...';
+$string['extensionduedate'] = 'Extension due date';
+$string['extensionnotafterduedate'] = 'Extension date must be after the due date';
+$string['extensionnotafterfromdate'] = 'Extension date must be after the allow submissions from date';
$string['gradersubmissionupdatedtext'] = '{$a->username} has updated their assignment submission
for \'{$a->assignment}\' at {$a->timeupdated}
@@ -103,6 +112,8 @@
for <i>\'{$a->assignment}\' at {$a->timeupdated}</i><br /><br />
It is <a href="{$a->url}">available on the web site</a>.';
$string['gradersubmissionupdatedsmall'] = '{$a->username} has updated their submission for assignment {$a->assignment}.';
+$string['grantextension'] = 'Grant extension';
+$string['grantextensionforusers'] = 'Grant extension for {$a} students';
$string['enabled'] = 'Enabled';
$string['errornosubmissions'] = 'There are no submissions to download';
$string['errorquickgradingvsadvancedgrading'] = 'The grades were not saved because this assignment is currently using advanced grading';
@@ -148,6 +159,8 @@
$string['invalidfloatforgrade'] = 'The grade provided could not be understood: {$a}';
$string['lastmodifiedsubmission'] = 'Last modified (submission)';
$string['lastmodifiedgrade'] = 'Last modified (grade)';
+$string['latesubmissions'] = 'Late submissions';
+$string['latesubmissionsaccepted'] = 'Only student(s) having been granted extension can still submit the assignment';
$string['locksubmissionforstudent'] = 'Prevent any more submissions for student: (id={$a->id}, fullname={$a->fullname}).';
$string['locksubmissions'] = 'Lock submissions';
$string['manageassignfeedbackplugins'] = 'Manage assignment feedback plugins';
@@ -165,9 +178,12 @@
$string['newsubmissions'] = 'Assignments submitted';
$string['nofiles'] = 'No files. ';
$string['nograde'] = 'No grade. ';
+$string['nolatesubmissions'] = 'No late submissions accepted. ';
$string['noonlinesubmissions'] = 'This assignment does not require you to submit anything online';
$string['nosavebutnext'] = 'Next';
$string['nosubmission'] = 'Nothing has been submitted for this assignment';
+$string['nosubmissionsacceptedafter'] = 'No submissions accepted after ';
+$string['nomoresubmissionsaccepted'] = 'No more submissions accepted';
$string['notgraded'] = 'Not graded';
$string['notgradedyet'] = 'Not graded yet';
$string['notsubmittedyet'] = 'Not submitted yet';
@@ -178,14 +194,13 @@
$string['numberofsubmittedassignments'] = 'Submitted';
$string['numberofsubmissionsneedgrading'] = 'Needs grading';
$string['offline'] = 'No online submissions required';
+$string['open'] = 'Open';
$string['overdue'] = '<font color="red">Assignment is overdue by: {$a}</font>';
$string['outlinegrade'] = 'Grade: {$a}';
$string['page-mod-assign-x'] = 'Any assignment module page';
$string['page-mod-assign-view'] = 'Assignment module main and submission page';
$string['pluginadministration'] = 'Assignment administration';
$string['pluginname'] = 'Assignment';
-$string['preventlatesubmissions'] = 'Prevent late submissions';
-$string['preventlatesubmissions_help'] = 'If enabled, students will not be able submit after the Due Date. If disabled, students will be able to submit assignments after the due date.';
$string['preventsubmissions'] = 'Prevent the user from making any more submissions to this assignment.';
$string['preventsubmissionsshort'] = 'Prevent submission changes';
$string['previous'] = 'Previous';
@@ -213,6 +228,8 @@
$string['showrecentsubmissions'] = 'Show recent submissions';
$string['submissiondrafts'] = 'Require students click submit button';
$string['submissiondrafts_help'] = 'If enabled, students will have to click a Submit button to declare their submission as final. This allows students to keep a draft version of the submission on the system. If this setting is changed from "No" to "Yes" after students have already submitted those submissions will be regarded as final.';
+$string['submissioneditable'] = 'Student can edit this submission';
+$string['submissionnoteditable'] = 'Student cannot edit this submission';
$string['submissionnotready'] = 'This assignment is not ready to submit:';
$string['submissionplugins'] = 'Submission plugins';
$string['submissionreceipts'] = 'Send submission receipts';
@@ -258,6 +275,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['viewfeedback'] = 'View feedback';
$string['viewfeedbackforuser'] = 'View feedback for user: {$a}';
$string['viewfullgradingpage'] = 'Open the full grading page to provide feedback';
View
21 mod/assign/lib.php
@@ -216,9 +216,14 @@ function assign_print_overview($courses, &$htmlarray) {
$time = time();
$isopen = false;
if ($assignment->duedate) {
- $isopen = $assignment->allowsubmissionsfromdate <= $time;
- if ($assignment->preventlatesubmissions) {
- $isopen = ($isopen && $time <= $assignment->duedate);
+ $duedate = false;
+ if ($assignment->cutoffdate) {
+ $duedate = $assignment->cutoffdate;
+ }
+ if ($duedate) {
+ $isopen = ($assignment->allowsubmissionsfromdate <= $time && $time <= $duedate);
+ } else {
+ $isopen = ($assignment->allowsubmissionsfromdate <= $time);
}
}
if ($isopen) {
@@ -232,6 +237,9 @@ function assign_print_overview($courses, &$htmlarray) {
}
$strduedate = get_string('duedate', 'assign');
+ $strcutoffdate = get_string('nosubmissionsacceptedafter', 'assign');
+ $strnolatesubmissions = get_string('nolatesubmissions', 'assign');
+ $strduedateno = get_string('duedateno', 'assign');
$strduedateno = get_string('duedateno', 'assign');
$strgraded = get_string('graded', 'assign');
$strnotgradedyet = get_string('notgradedyet', 'assign');
@@ -279,6 +287,13 @@ function assign_print_overview($courses, &$htmlarray) {
} else {
$str .= '<div class="info">'.$strduedateno.'</div>';
}
+ if ($assignment->cutoffdate) {
+ if ($assignment->cutoffdate == $assignment->duedate) {
+ $str .= '<div class="info">'.$strnolatesubmissions.'</div>';
+ } else {
+ $str .= '<div class="info">'.$strcutoffdate.': '.userdate($assignment->cutoffdate).'</div>';
+ }
+ }
$context = context_module::instance($assignment->coursemodule);
if (has_capability('mod/assign:grade', $context)) {
View
230 mod/assign/locallib.php
@@ -303,25 +303,24 @@ public function view($action='') {
if ($this->process_save_submission($mform)) {
$action = 'view';
}
- } else if ($action == 'lock') {
+ } else if ($action == 'lock') {
$this->process_lock();
$action = 'grading';
- } else if ($action == 'reverttodraft') {
+ } else if ($action == 'reverttodraft') {
$this->process_revert_to_draft();
$action = 'grading';
- } else if ($action == 'unlock') {
+ } else if ($action == 'unlock') {
$this->process_unlock();
$action = 'grading';
- } else if ($action == 'confirmsubmit') {
+ } else if ($action == 'confirmsubmit') {
$action = 'submit';
if ($this->process_submit_for_grading($mform)) {
$action = 'view';
}
// save and show next button
- } else if ($action == 'batchgradingoperation') {
- $this->process_batch_grading_operation();
- $action = 'grading';
- } else if ($action == 'submitgrade') {
+ } else if ($action == 'batchgradingoperation') {
+ $action = $this->process_batch_grading_operation();
+ } else if ($action == 'submitgrade') {
if (optional_param('saveandshownext', null, PARAM_ALPHA)) {
//save and show next
$action = 'grade';
@@ -343,12 +342,17 @@ public function view($action='') {
//cancel button
$action = 'grading';
}
- }else if ($action == 'quickgrade') {
+ } else if ($action == 'quickgrade') {
$message = $this->process_save_quick_grades();
$action = 'quickgradingresult';
- }else if ($action == 'saveoptions') {
+ } else if ($action == 'saveoptions') {
$this->process_save_grading_options();
$action = 'grading';
+ } else if ($action == 'saveextension') {
+ $action = 'grantextension';
+ if ($this->process_save_extension($mform)) {
+ $action = 'grading';
+ }
}
$returnparams = array('rownum'=>optional_param('rownum', 0, PARAM_INT));
@@ -378,6 +382,8 @@ public function view($action='') {
$o .= $this->download_submissions();
} else if ($action == 'submit') {
$o .= $this->check_submit_for_grading($mform);
+ } else if ($action == 'grantextension') {
+ $o .= $this->view_grant_extension($mform);
} else {
$o .= $this->view_submission_page();
}
@@ -409,12 +415,12 @@ public function add_instance(stdClass $formdata, $callplugins) {
$update->intro = $formdata->intro;
$update->introformat = $formdata->introformat;
$update->alwaysshowdescription = $formdata->alwaysshowdescription;
- $update->preventlatesubmissions = $formdata->preventlatesubmissions;
$update->submissiondrafts = $formdata->submissiondrafts;
$update->requiresubmissionstatement = $formdata->requiresubmissionstatement;
$update->sendnotifications = $formdata->sendnotifications;
$update->sendlatenotifications = $formdata->sendlatenotifications;
$update->duedate = $formdata->duedate;
+ $update->cutoffdate = $formdata->cutoffdate;
$update->allowsubmissionsfromdate = $formdata->allowsubmissionsfromdate;
$update->grade = $formdata->grade;
$update->completionsubmit = !empty($formdata->completionsubmit);
@@ -629,12 +635,12 @@ public function update_instance($formdata) {
$update->intro = $formdata->intro;
$update->introformat = $formdata->introformat;
$update->alwaysshowdescription = $formdata->alwaysshowdescription;
- $update->preventlatesubmissions = $formdata->preventlatesubmissions;
$update->submissiondrafts = $formdata->submissiondrafts;
$update->requiresubmissionstatement = $formdata->requiresubmissionstatement;
$update->sendnotifications = $formdata->sendnotifications;
$update->sendlatenotifications = $formdata->sendlatenotifications;
$update->duedate = $formdata->duedate;
+ $update->cutoffdate = $formdata->cutoffdate;
$update->allowsubmissionsfromdate = $formdata->allowsubmissionsfromdate;
$update->grade = $formdata->grade;
$update->completionsubmit = !empty($formdata->completionsubmit);
@@ -1271,6 +1277,56 @@ private function update_grade($grade) {
}
/**
+ * View the grant extension date page
+ *
+ * Uses url parameters 'userid'
+ * or from parameter 'selectedusers'
+ * @param moodleform $mform - Used for validation of the submitted data
+ * @return string
+ */
+ private function view_grant_extension($mform) {
+ global $DB, $CFG;
+ require_once($CFG->dirroot . '/mod/assign/extensionform.php');
+
+ $o = '';
+ $batchusers = optional_param('selectedusers', '', PARAM_TEXT);
+ $data = new stdClass();
+ $data->extensionduedate = null;
+ $userid = 0;
+ if (!$batchusers) {
+ $userid = required_param('userid', PARAM_INT);
+
+ $grade = $this->get_user_grade($userid, false);
+
+ $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
+
+ if ($grade) {
+ $data->extensionduedate = $grade->extensionduedate;
+ }
+ $data->userid = $userid;
+ } else {
+ $data->batchusers = $batchusers;
+ }
+ $o .= $this->output->render(new assign_header($this->get_instance(),
+ $this->get_context(),
+ $this->show_intro(),
+ $this->get_course_module()->id,
+ get_string('grantextension', 'assign')));
+
+ if (!$mform) {
+ $mform = new mod_assign_extension_form(null, array($this->get_course_module()->id,
+ $userid,
+ $batchusers,
+ $this->get_instance(),
+ $data));
+ }
+ $o .= $this->output->render(new assign_form('extensionform', $mform));
+ $o .= $this->view_footer();
+ return $o;
+ }
+
+
+ /**
* display the submission that is used by a plugin
* Uses url parameters 'sid', 'gid' and 'plugin'
* @param string $pluginsubtype
@@ -1652,20 +1708,31 @@ private function view_single_grade_page($mform, $offset=0) {
$grade = $this->get_user_grade($userid, false);
if ($this->can_view_submission($userid)) {
$gradelocked = ($grade && $grade->locked) || $this->grading_disabled($userid);
+ $extensionduedate = null;
+ if ($grade) {
+ $extensionduedate = $grade->extensionduedate;
+ }
+ $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);
+
$o .= $this->output->render(new assign_submission_status($this->get_instance()->allowsubmissionsfromdate,
$this->get_instance()->alwaysshowdescription,
$submission,
$this->is_any_submission_plugin_enabled(),
$gradelocked,
$this->is_graded($userid),
$this->get_instance()->duedate,
+ $this->get_instance()->cutoffdate,
$this->get_submission_plugins(),
$this->get_return_action(),
$this->get_return_params(),
$this->get_course_module()->id,
assign_submission_status::GRADER_VIEW,
- false,
- false));
+ $showedit,
+ $showsubmit,
+ $extensionduedate));
}
if ($grade) {
$data = new stdClass();
@@ -1760,7 +1827,8 @@ private function view_grading_table() {
$gradingbatchoperationsform = new mod_assign_grading_batch_operations_form(null,
array('cm'=>$this->get_course_module()->id,
- 'submissiondrafts'=>$this->get_instance()->submissiondrafts),
+ 'submissiondrafts'=>$this->get_instance()->submissiondrafts,
+ 'duedate'=>$this->get_instance()->duedate),
'post', '',
array('class'=>'gradingbatchoperationsform'));
@@ -1946,7 +2014,7 @@ public function can_view_submission($userid) {
/**
* Ask the user to confirm they want to perform this batch operation
- * @return string
+ * @return string - the page to view after processing these actions
*/
private function process_batch_grading_operation() {
global $CFG;
@@ -1955,7 +2023,8 @@ private function process_batch_grading_operation() {
$gradingbatchoperationsform = new mod_assign_grading_batch_operations_form(null,
array('cm'=>$this->get_course_module()->id,
- 'submissiondrafts'=>$this->get_instance()->submissiondrafts),
+ 'submissiondrafts'=>$this->get_instance()->submissiondrafts,
+ 'duedate'=>$this->get_instance()->duedate),
'post', '',
array('class'=>'gradingbatchoperationsform'));
@@ -1971,11 +2040,13 @@ private function process_batch_grading_operation() {
$this->process_unlock($userid);
} else if ($data->operation == 'reverttodraft') {
$this->process_revert_to_draft($userid);
+ } else if ($data->operation == 'grantextension') {
+ return 'grantextension';
}
}
}
- return true;
+ return 'grading';
}
/**
@@ -2044,24 +2115,29 @@ public function view_student_summary($user, $showlinks) {
if ($this->can_view_submission($user->id)) {
$showedit = has_capability('mod/assign:submit', $this->context) &&
- $this->submissions_open() && ($this->is_any_submission_plugin_enabled()) && $showlinks;
+ $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);
-
+ $extensionduedate = null;
+ if ($grade) {
+ $extensionduedate = $grade->extensionduedate;
+ }
$o .= $this->output->render(new assign_submission_status($this->get_instance()->allowsubmissionsfromdate,
$this->get_instance()->alwaysshowdescription,
$submission,
$this->is_any_submission_plugin_enabled(),
$gradelocked,
$this->is_graded($user->id),
$this->get_instance()->duedate,
+ $this->get_instance()->cutoffdate,
$this->get_submission_plugins(),
$this->get_return_action(),
$this->get_return_params(),
$this->get_course_module()->id,
assign_submission_status::STUDENT_VIEW,
$showedit,
- $showsubmit));
+ $showsubmit,
+ $extensionduedate));
require_once($CFG->libdir.'/gradelib.php');
require_once($CFG->dirroot.'/grade/grading/lib.php');
@@ -2142,6 +2218,7 @@ private function view_submission_page() {
$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()
@@ -2257,15 +2334,35 @@ private function update_submission(stdClass $submission, $updatetime=true) {
* has this person already submitted,
* is the assignment locked?
*
+ * @param int $userid - Optional userid so we can see if a different user can submit
* @return bool
*/
- private function submissions_open() {
+ private function submissions_open($userid = 0) {
global $USER;
+ if (!$userid) {
+ $userid = $USER->id;
+ }
+
$time = time();
$dateopen = true;
- if ($this->get_instance()->preventlatesubmissions && $this->get_instance()->duedate) {
- $dateopen = ($this->get_instance()->allowsubmissionsfromdate <= $time && $time <= $this->get_instance()->duedate);
+ $finaldate = false;
+ if ($this->get_instance()->cutoffdate) {
+ $finaldate = $this->get_instance()->cutoffdate;
+ }
+ // User extensions.
+ if ($finaldate) {
+ $grade = $this->get_user_grade($userid, false);
+ if ($grade && $grade->extensionduedate) {
+ // Extension can be before cut off date.
+ if ($grade->extensionduedate > $finaldate) {
+ $finaldate = $grade->extensionduedate;
+ }
+ }
+ }
+
+ if ($finaldate) {
+ $dateopen = ($this->get_instance()->allowsubmissionsfromdate <= $time && $time <= $finaldate);
} else {
$dateopen = ($this->get_instance()->allowsubmissionsfromdate <= $time);
}
@@ -2274,23 +2371,23 @@ private function submissions_open() {
return false;
}
- // now check if this user has already submitted etc.
- if (!is_enrolled($this->get_course_context(), $USER)) {
+ // Now check if this user has already submitted etc.
+ if (!is_enrolled($this->get_course_context(), $userid)) {
return false;
}
- if ($submission = $this->get_user_submission($USER->id, false)) {
+ if ($submission = $this->get_user_submission($userid, false)) {
if ($this->get_instance()->submissiondrafts && $submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED) {
// drafts are tracked and the student has submitted the assignment
return false;
}
}
- if ($grade = $this->get_user_grade($USER->id, false)) {
+ if ($grade = $this->get_user_grade($userid, false)) {
if ($grade->locked) {
return false;
}
}
- if ($this->grading_disabled($USER->id)) {
+ if ($this->grading_disabled($userid)) {
return false;
}
@@ -2477,7 +2574,6 @@ public function send_notification($userfrom, $userto, $messagetype, $eventtype,
/**
* Notify student upon successful submission
*
- * @global moodle_database $DB
* @param stdClass $submission
* @return void
*/
@@ -2496,7 +2592,6 @@ private function notify_student_submission_receipt(stdClass $submission) {
/**
* Send notifications to graders upon student submissions
*
- * @global moodle_database $DB
* @param stdClass $submission
* @return void
*/
@@ -2580,9 +2675,77 @@ private function process_submit_for_grading($mform) {
}
/**
+ * save the extension date for a single user
+ *
+ * @param int $userid The user id
+ * @param mixed $extensionduedate Either an integer date or null
+ * @return boolean
+ */
+ private function save_user_extension($userid, $extensionduedate) {
+ global $DB;
+
+ $grade = $this->get_user_grade($userid, true);
+ $grade->extensionduedate = $extensionduedate;
+ $grade->timemodified = time();
+
+ $result = $DB->update_record('assign_grades', $grade);
+
+ if ($result) {
+ $this->add_to_log('grant extension', $this->format_grade_for_log($grade));
+ }
+ return $result;
+ }
+
+ /**
+ * save extension date
+ *
+ * @param moodleform $mform The submitted form
+ * @return boolean
+ */
+ private function process_save_extension(& $mform) {
+ global $DB, $CFG;
+
+ // 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_TEXT);
+ $userid = 0;
+ if (!$batchusers) {
+ $userid = required_param('userid', PARAM_INT);
+ $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
+ }
+ $mform = new mod_assign_extension_form(null, array($this->get_course_module()->id,
+ $userid,
+ $batchusers,
+ $this->get_instance(),
+ null));
+
+ if ($mform->is_cancelled()) {
+ return true;
+ }
+
+ if ($formdata = $mform->get_data()) {
+ if ($batchusers) {
+ $users = explode(',', $batchusers);
+ $result = true;
+ foreach ($users as $userid) {
+ $result = $this->save_user_extension($userid, $formdata->extensionduedate) && $result;
+ }
+ return $result;
+ } else {
+ return $this->save_user_extension($userid, $formdata->extensionduedate);
+ }
+ }
+ return false;
+ }
+
+
+ /**
* save quick grades
*
- * @global moodle_database $DB
* @return string The result of the save operation
*/
private function process_save_quick_grades() {
@@ -2771,6 +2934,9 @@ private function format_grade_for_log(stdClass $grade) {
if ($grade->locked) {
$info .= get_string('submissionslocked', 'assign') . '. ';
}
+ if ($grade->extensionduedate) {
+ $info .= get_string('userextensiondate', 'assign', userdate($grade->extensionduedate));
+ }
return $info;
}
View
17 mod/assign/mod_form.php
@@ -82,12 +82,12 @@ function definition() {
$mform->addElement('date_time_selector', 'duedate', get_string('duedate', 'assign'), array('optional'=>true));
$mform->addHelpButton('duedate', 'duedate', 'assign');
$mform->setDefault('duedate', time()+7*24*3600);
+ $mform->addElement('date_time_selector', 'cutoffdate', get_string('cutoffdate', 'assign'), array('optional'=>true));
+ $mform->addHelpButton('cutoffdate', 'cutoffdate', 'assign');
+ $mform->setDefault('cutoffdate', time()+7*24*3600);
$mform->addElement('selectyesno', 'alwaysshowdescription', get_string('alwaysshowdescription', 'assign'));
$mform->addHelpButton('alwaysshowdescription', 'alwaysshowdescription', 'assign');
$mform->setDefault('alwaysshowdescription', 1);
- $mform->addElement('selectyesno', 'preventlatesubmissions', get_string('preventlatesubmissions', 'assign'));
- $mform->addHelpButton('preventlatesubmissions', 'preventlatesubmissions', 'assign');
- $mform->setDefault('preventlatesubmissions', 0);
$mform->addElement('selectyesno', 'submissiondrafts', get_string('submissiondrafts', 'assign'));
$mform->addHelpButton('submissiondrafts', 'submissiondrafts', 'assign');
$mform->setDefault('submissiondrafts', 0);
@@ -150,6 +150,17 @@ function validation($data, $files) {
$errors['duedate'] = get_string('duedatevalidation', 'assign');
}
}
+ if ($data['duedate'] && $data['cutoffdate']) {
+ if ($data['duedate'] > $data['cutoffdate']) {
+ $errors['cutoffdate'] = get_string('cutoffdatevalidation', 'assign');
+ }
+ }
+ if ($data['allowsubmissionsfromdate'] && $data['cutoffdate']) {
+ if ($data['allowsubmissionsfromdate'] > $data['cutoffdate']) {
+ $errors['cutoffdate'] = get_string('cutoffdatefromdatevalidation', 'assign');
+ }
+ }
+
return $errors;
}
View
20 mod/assign/renderable.php
@@ -297,6 +297,8 @@ class assign_submission_status implements renderable {
var $graded = false;
/** @var int duedate */
var $duedate = 0;
+ /** @var int cutoffdate */
+ public $cutoffdate = 0;
/** @var array submissionplugins - the list of submission plugins */
var $submissionplugins = array();
/** @var string returnaction */
@@ -311,6 +313,8 @@ class assign_submission_status implements renderable {
var $canedit = false;
/** @var bool cansubmit */
var $cansubmit = false;
+ /** @var int extensionduedate */
+ public $extensionduedate = 0;
/**
* constructor
@@ -322,31 +326,35 @@ class assign_submission_status implements renderable {
* @param bool $locked
* @param bool $graded
* @param int $duedate
+ * @param int $cutoffdate
* @param array $submissionplugins
* @param string $returnaction
* @param array $returnparams
* @param int $coursemoduleid
* @param string $view
* @param bool $canedit
* @param bool $cansubmit
+ * @param int $extensionduedate - Any extension to the due date granted for this user
*/
public function __construct($allowsubmissionsfromdate, $alwaysshowdescription, $submission, $submissionsenabled,
- $locked, $graded, $duedate, $submissionplugins, $returnaction, $returnparams,
- $coursemoduleid, $view, $canedit, $cansubmit) {
+ $locked, $graded, $duedate, $cutoffdate, $submissionplugins, $returnaction, $returnparams,
+ $coursemoduleid, $view, $canedit, $cansubmit, $extensionduedate) {
$this->allowsubmissionsfromdate = $allowsubmissionsfromdate;
$this->alwaysshowdescription = $alwaysshowdescription;
$this->submission = $submission;
$this->submissionsenabled = $submissionsenabled;
$this->locked = $locked;
$this->graded = $graded;
$this->duedate = $duedate;
+ $this->cutoffdate = $cutoffdate;
$this->submissionplugins = $submissionplugins;
$this->returnaction = $returnaction;
$this->returnparams = $returnparams;
$this->coursemoduleid = $coursemoduleid;
$this->view = $view;
$this->canedit = $canedit;
$this->cansubmit = $cansubmit;
+ $this->extensionduedate = $extensionduedate;
}
}
@@ -412,6 +420,8 @@ class assign_grading_summary implements renderable {
var $submissionsneedgradingcount = 0;
/** @var int duedate - The assignment due date (if one is set) */
var $duedate = 0;
+ /** @var int cutoffdate - The assignment cut off date (if one is set) */
+ var $cutoffdate = 0;
/** @var int coursemoduleid - The assignment course module id */
var $coursemoduleid = 0;
@@ -423,23 +433,25 @@ class assign_grading_summary implements renderable {
* @param int $submissiondraftscount
* @param bool $submissionsenabled
* @param int $submissionssubmittedcount
+ * @param int $cutoffdate
* @param int $duedate
* @param int $coursemoduleid
+ * @param int $submissionsneedgradingcount
*/
public function __construct($participantcount, $submissiondraftsenabled, $submissiondraftscount,
$submissionsenabled, $submissionssubmittedcount,
- $duedate, $coursemoduleid, $submissionsneedgradingcount) {
+ $cutoffdate, $duedate, $coursemoduleid, $submissionsneedgradingcount) {
$this->participantcount = $participantcount;
$this->submissiondraftsenabled = $submissiondraftsenabled;
$this->submissiondraftscount = $submissiondraftscount;
$this->submissionsenabled = $submissionsenabled;
$this->submissionssubmittedcount = $submissionssubmittedcount;
$this->duedate = $duedate;
+ $this->cutoffdate = $cutoffdate;
$this->coursemoduleid = $coursemoduleid;
$this->submissionsneedgradingcount = $submissionsneedgradingcount;
}
-
}
/**
View
99 mod/assign/renderer.php
@@ -265,6 +265,19 @@ public function render_assign_grading_summary(assign_grading_summary $summary) {
$due = format_time($duedate - $time);
}
$this->add_table_row_tuple($t, get_string('timeremaining', 'assign'), $due);
+
+ if ($duedate < $time) {
+ $cutoffdate = $summary->cutoffdate;
+ if ($cutoffdate) {
+ if ($cutoffdate > $time) {
+ $late = get_string('latesubmissionsaccepted', 'assign');
+ } else {
+ $late = get_string('nomoresubmissionsaccepted', 'assign');
+ }
+ $this->add_table_row_tuple($t, get_string('latesubmissions', 'assign'), $late);
+ }
+ }
+
}
// all done - write the table
@@ -406,14 +419,33 @@ public function render_assign_submission_status(assign_submission_status $status
$duedate = $status->duedate;
- if ($duedate >= 1) {
+ if ($duedate > 0) {
$row = new html_table_row();
$cell1 = new html_table_cell(get_string('duedate', 'assign'));
$cell2 = new html_table_cell(userdate($duedate));
$row->cells = array($cell1, $cell2);
$t->data[] = $row;
- // time remaining
+ if ($status->view == assign_submission_status::GRADER_VIEW) {
+ if ($status->cutoffdate) {
+ $row = new html_table_row();
+ $cell1 = new html_table_cell(get_string('cutoffdate', 'assign'));
+ $cell2 = new html_table_cell(userdate($status->cutoffdate));
+ $row->cells = array($cell1, $cell2);
+ $t->data[] = $row;
+ }
+ }
+
+ if ($status->extensionduedate) {
+ $row = new html_table_row();
+ $cell1 = new html_table_cell(get_string('extensionduedate', 'assign'));
+ $cell2 = new html_table_cell(userdate($status->extensionduedate));
+ $row->cells = array($cell1, $cell2);
+ $t->data[] = $row;
+ $duedate = $status->extensionduedate;
+ }
+
+ // Time remaining.
$row = new html_table_row();
$cell1 = new html_table_cell(get_string('timeremaining', 'assign'));
if ($duedate - $time <= 0) {
@@ -440,7 +472,22 @@ public function render_assign_submission_status(assign_submission_status $status
$t->data[] = $row;
}
- // last modified
+ // Show graders whether this submission is editable by students.
+ if ($status->view == assign_submission_status::GRADER_VIEW) {
+ $row = new html_table_row();
+ $cell1 = new html_table_cell(get_string('open', 'assign'));
+ if ($status->canedit) {
+ $cell2 = new html_table_cell(get_string('submissioneditable', 'assign'));
+ $cell2->attributes = array('class'=>'submissioneditable');
+ } else {
+ $cell2 = new html_table_cell(get_string('submissionnoteditable', 'assign'));
+ $cell2->attributes = array('class'=>'submissionnoteditable');
+ }
+ $row->cells = array($cell1, $cell2);
+ $t->data[] = $row;
+ }
+
+ // Last modified.
if ($status->submission) {
$row = new html_table_row();
$cell1 = new html_table_cell(get_string('timemodified', 'assign'));
@@ -452,7 +499,12 @@ public function render_assign_submission_status(assign_submission_status $status
if ($plugin->is_enabled() && $plugin->is_visible() && !$plugin->is_empty($status->submission)) {
$row = new html_table_row();
$cell1 = new html_table_cell($plugin->get_name());
- $pluginsubmission = new assign_submission_plugin_submission($plugin, $status->submission, assign_submission_plugin_submission::SUMMARY, $status->coursemoduleid, $status->returnaction, $status->returnparams);
+ $pluginsubmission = new assign_submission_plugin_submission($plugin,
+ $status->submission,
+ assign_submission_plugin_submission::SUMMARY,
+ $status->coursemoduleid,
+ $status->returnaction,
+ $status->returnparams);
$cell2 = new html_table_cell($this->render($pluginsubmission));
$row->cells = array($cell1, $cell2);
$t->data[] = $row;
@@ -464,24 +516,28 @@ public function render_assign_submission_status(assign_submission_status $status
$o .= html_writer::table($t);
$o .= $this->output->box_end();
- // links
- if ($status->canedit) {
- if (!$status->submission) {
- $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php',
- array('id' => $status->coursemoduleid, 'action' => 'editsubmission')), get_string('addsubmission', 'assign'), 'get');
- } else {
- $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php',
- array('id' => $status->coursemoduleid, 'action' => 'editsubmission')), get_string('editsubmission', 'assign'), 'get');
+ // Links.
+ if ($status->view == assign_submission_status::STUDENT_VIEW) {
+ if ($status->canedit) {
+ if (!$status->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');
+ } else {
+ $urlparams = array('id' => $status->coursemoduleid, 'action' => 'editsubmission');
+ $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams),
+ get_string('editsubmission', 'assign'), 'get');
+ }
}
- }
- if ($status->cansubmit) {
- // submission.php
- $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php',
- array('id' => $status->coursemoduleid, 'action'=>'submit')), get_string('submitassignment', 'assign'), 'get');
- $o .= $this->output->box_start('boxaligncenter submithelp');
- $o .= get_string('submitassignment_help', 'assign');
- $o .= $this->output->box_end();
+ if ($status->cansubmit) {
+ $urlparams = array('id' => $status->coursemoduleid, 'action'=>'submit');
+ $o .= $this->output->single_button(new moodle_url('/mod/assign/view.php', $urlparams),
+ get_string('submitassignment', 'assign'), 'get');
+ $o .= $this->output->box_start('boxaligncenter submithelp');
+ $o .= get_string('submitassignment_help', 'assign');
+ $o .= $this->output->box_end();
+ }
}
$o .= $this->output->container_end();
@@ -537,9 +593,10 @@ public function render_assign_grading_table(assign_grading_table $table) {
$o .= $this->output->box_start('boxaligncenter gradingtable');
$this->page->requires->js_init_call('M.mod_assign.init_grading_table', array());
$this->page->requires->string_for_js('nousersselected', 'assign');
+ $this->page->requires->string_for_js('batchoperationconfirmgrantextension', 'assign');
$this->page->requires->string_for_js('batchoperationconfirmlock', 'assign');
- $this->page->requires->string_for_js('batchoperationconfirmunlock', 'assign');
$this->page->requires->string_for_js('batchoperationconfirmreverttodraft', 'assign');
+ $this->page->requires->string_for_js('batchoperationconfirmunlock', 'assign');
$this->page->requires->string_for_js('editaction', 'assign');
// need to get from prefs
$o .= $this->flexible_table($table, $table->get_rows_per_page(), true);
View
4 mod/assign/styles.css
@@ -130,3 +130,7 @@ div.earlysubmission {
#page-mod-assign-view div.gradingtable tr .quickgrademodified {
background-color: #FFCC99;
}
+
+td.submissioneditable {
+ color: red;
+}
View
6 mod/assign/upgradelib.php
@@ -89,8 +89,12 @@ public function upgrade_assignment($oldassignmentid, & $log) {
$data->allowsubmissionsfromdate = $oldassignment->timeavailable;
$data->grade = $oldassignment->grade;
$data->submissiondrafts = $oldassignment->resubmit;
- $data->preventlatesubmissions = $oldassignment->preventlate;
$data->requiresubmissionstatement = 0;
+ $data->cutoffdate = 0;
+ // New way to specify no late submissions.
+ if ($oldassignment->preventlate) {
+ $data->cutoffdate = $data->duedate;
+ }
$newassignment = new assign(null, null, null);
View
2 mod/assign/version.php
@@ -25,7 +25,7 @@
defined('MOODLE_INTERNAL') || die();
$module->component = 'mod_assign'; // Full name of the plugin (used for diagnostics)
-$module->version = 2012081600; // The current module version (Date: YYYYMMDDXX)
+$module->version = 2012082100; // The current module version (Date: YYYYMMDDXX)
$module->requires = 2012061700; // Requires this Moodle version
$module->cron = 60;

0 comments on commit 9e79517

Please sign in to comment.
Something went wrong with that request. Please try again.