diff -Naur moodle2.2_ori//mod/assignment/db/access.php moodle2.2//mod/assignment/db/access.php --- moodle2.2_ori//mod/assignment/db/access.php 2010-05-22 05:32:07.000000000 +0530 +++ moodle2.2//mod/assignment/db/access.php 2012-04-03 21:12:27.000000000 +0530 @@ -75,6 +75,17 @@ 'student' => CAP_ALLOW, ) ), + + 'mod/assignment:individualextension'=>array( + 'captype'=>'write', + 'contextlevel'=> CONTEXT_MODULE, + 'archetypes' =>array( + 'teacher' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + 'manager' => CAP_allow, + ) + ), + ); diff -Naur moodle2.2_ori//mod/assignment/db/install.xml moodle2.2//mod/assignment/db/install.xml --- moodle2.2_ori//mod/assignment/db/install.xml 2009-05-02 05:34:38.000000000 +0530 +++ moodle2.2//mod/assignment/db/install.xml 2012-04-03 22:03:05.000000000 +0530 @@ -1,5 +1,5 @@ - @@ -33,7 +33,7 @@ - +
@@ -60,5 +60,25 @@
+ + + + + + + + + + + + + + + + + + + +
-
\ No newline at end of file + diff -Naur moodle2.2_ori//mod/assignment/db/upgrade.php moodle2.2//mod/assignment/db/upgrade.php --- moodle2.2_ori//mod/assignment/db/upgrade.php 2011-12-10 05:34:20.000000000 +0530 +++ moodle2.2//mod/assignment/db/upgrade.php 2012-04-03 22:02:42.000000000 +0530 @@ -128,7 +128,7 @@ upgrade_mod_savepoint(true, 2008081900, 'assignment'); } - if ($oldversion < 2009042000) { + if ($oldversion < 2009042001) { /// Rename field description on table assignment to intro $table = new xmldb_table('assignment'); @@ -159,6 +159,38 @@ // Moodle v2.2.0 release upgrade line // Put any upgrade step following this + if ($oldversion < 2012040400) { + + // Define table assignment_extensions to be created + $table = new xmldb_table('assignment_extensions'); + + // Adding fields to table assignment_extensions + $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); + $table->add_field('assignmentid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + $table->add_field('extension', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + $table->add_field('extensioncomment', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, null, null); + $table->add_field('timegiven', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + $table->add_field('teacher', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + $table->add_field('final', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'); + + // Adding keys to table assignment_extensions + $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); + $table->add_key('assignmentid', XMLDB_KEY_FOREIGN, array('assignmentid'), 'assignment', array('id')); + + // Adding indexes to table assignment_extensions + $table->add_index('userid', XMLDB_INDEX_NOTUNIQUE, array('userid')); + + // Conditionally launch create table for assignment_extensions + if (!$dbman->table_exists($table)) { + $dbman->create_table($table); + } + + // assignment savepoint reached + upgrade_mod_savepoint(true, 2012040401, 'assignment'); + } + return true; } diff -Naur moodle2.2_ori//mod/assignment/extensions.php moodle2.2//mod/assignment/extensions.php --- moodle2.2_ori//mod/assignment/extensions.php 1970-01-01 05:30:00.000000000 +0530 +++ moodle2.2//mod/assignment/extensions.php 2012-04-07 13:11:45.253873261 +0530 @@ -0,0 +1,55 @@ +get_record("assignment", array("id"=>$cm->instance))) { + print_error('invalidid', 'assignment'); + } + + if (! $course = $DB->get_record("course", array("id"=>$assignment->course))) { + print_error('coursemisconf', 'assignment'); + } + $url->param('id', $id); +} else { + if (!$assignment = $DB->get_record("assignment", array("id"=>$a))) { + print_error('invalidcoursemodule'); + } + if (! $course = $DB->get_record("course", array("id"=>$assignment->course))) { + print_error('coursemisconf', 'assignment'); + } + if (! $cm = get_coursemodule_from_instance("assignment", $assignment->id, $course->id)) { + print_error('invalidcoursemodule'); + } + $url->param('a', $a); +} + +if ($mode !== 'all') { + $url->param('mode', $mode); +} +$PAGE->set_url($url); +require_login($course->id, false, $cm); + + +require_capability('mod/assignment:individualextension', get_context_instance(CONTEXT_MODULE, $cm->id)); + +$PAGE->requires->js('/mod/assignment/assignment.js'); + + +/// Load up the required assignment code +require($CFG->dirroot.'/mod/assignment/type/'.$assignment->assignmenttype.'/assignment.class.php'); + + +$assignmentclass = 'assignment_'.$assignment->assignmenttype; +$assignmentinstance = new $assignmentclass($cm->id, $assignment, $cm, $course); + +$assignmentinstance->extensions($mode); //display extensions + +?> diff -Naur moodle2.2_ori//mod/assignment/lang/en/assignment.php moodle2.2//mod/assignment/lang/en/assignment.php --- moodle2.2_ori//mod/assignment/lang/en/assignment.php 2011-12-06 14:52:45.000000000 +0530 +++ moodle2.2//mod/assignment/lang/en/assignment.php 2012-04-06 20:45:42.000000000 +0530 @@ -32,6 +32,7 @@ $string['allowresubmit'] = 'Allow resubmitting'; $string['allowresubmit_help'] = 'If enabled, students will be allowed to resubmit assignments after they have been graded (for them to be re-graded).'; $string['alreadygraded'] = 'Your assignment has already been graded and resubmission is not allowed.'; +$string['assignmentdates'] = 'Dates'; $string['assignmentdetails'] = 'Assignment details'; $string['assignment:exportownsubmission'] = 'Export own submission'; $string['assignment:exportsubmission'] = 'Export submission'; @@ -51,6 +52,7 @@ $string['assignment:submit'] = 'Submit assignment'; $string['assignmentsubmission'] = 'Assignment submissions'; $string['assignmenttype'] = 'Assignment type'; +$string['assignment:individualextension'] = 'Individual extension to assignment'; $string['assignment:view'] = 'View assignment'; $string['availabledate'] = 'Available from'; $string['cannotdeletefiles'] = 'An error occurred and files could not be deleted'; @@ -94,13 +96,20 @@ $string['emptysubmission'] = 'You have not submitted anything yet'; $string['enablenotification'] = 'Send notifications'; $string['enablenotification_help'] = 'If enabled, students will be notified when their assignment submissions are graded.'; +$string['epagesize'] = 'Extensions shown per page'; $string['errornosubmissions'] = 'There are no submissions to download'; $string['existingfiledeleted'] = 'Existing file has been deleted: {$a}'; +$string['extend'] = 'Extend'; +$string['extended'] = 'Extended'; +$string['extension'] = 'Extension'; +$string['extensioncomment'] = 'Extension comment'; +$string['extensions'] = 'Extensions'; $string['failedupdatefeedback'] = 'Failed to update submission feedback for user {$a}'; $string['feedback'] = 'Feedback'; $string['feedbackfromteacher'] = 'Feedback from {$a}'; $string['feedbackupdated'] = 'Submissions feedback updated for {$a} people'; $string['finalize'] = 'Prevent submission updates'; +$string['finalextension'] = 'Final extension'; $string['finalizeerror'] = 'An error occurred and that submission could not be finalised'; $string['graded'] = 'Graded'; $string['guestnosubmit'] = 'Sorry, guests are not allowed to submit an assignment. You have to log in/ register before you can submit your answer.'; @@ -132,6 +141,7 @@ $string['invalidtype'] = 'Invalid assignment type'; $string['invaliduserid'] = 'Invalid user ID'; $string['itemstocount'] = 'Count'; +$string['lastextended'] = 'Last extension'; $string['lastgrade'] = 'Last grade'; $string['late'] = '{$a} late'; $string['maximumgrade'] = 'Maximum grade'; @@ -144,6 +154,8 @@ $string['newsubmissions'] = 'Assignments submitted'; $string['noassignments'] = 'There are no assignments yet'; $string['noattempts'] = 'No attempts have been made on this assignment'; +$string['noextended'] = 'No user has yet given extension'; +$string['noextensionrequired'] = 'Sorry, no extension required for this assignment.
Preventlate or timedue is not set.'; $string['noblogs'] = 'You have no blog entries to submit!'; $string['nofiles'] = 'No files were submitted'; $string['nofilesyet'] = 'No files submitted yet'; @@ -153,6 +165,7 @@ $string['notesempty'] = 'No entry'; $string['notesupdateerror'] = 'Error when updating notes'; $string['notgradedyet'] = 'Not graded yet'; +$string['norequireextension'] = 'No user require extension'; $string['norequiregrading'] = 'There are no assignments that require grading'; $string['nosubmisson'] = 'No assignments have been submit'; $string['notsubmittedyet'] = 'Not submitted yet'; @@ -168,11 +181,14 @@ $string['pluginadministration'] = 'Assignment administration'; $string['pluginname'] = 'Assignment'; $string['preventlate'] = 'Prevent late submissions'; +$string['quickextend'] = 'Quickextend'; $string['quickgrade'] = 'Allow quick grading'; $string['quickgrade_help'] = 'If enabled, multiple assignments can be graded on one page. Add grades and comments then click the "Save all my feedback" button to save all changes for that page.'; $string['requiregrading'] = 'Require grading'; +$string['requireextension'] = 'Require extension'; $string['responsefiles'] = 'Response files'; $string['reviewed'] = 'Reviewed'; +$string['saveallextensions'] = 'Save all extensions'; $string['saveallfeedback'] = 'Save all my feedback'; $string['selectblog'] = 'Select which blog entry you wish to submit'; $string['sendformarking'] = 'Send for marking'; @@ -213,6 +229,7 @@ $string['usermisconf'] = 'User is misconfigured'; $string['usernosubmit'] = 'Sorry, you are not allowed to submit an assignment.'; $string['viewfeedback'] = 'View assignment grades and feedback'; +$string['viewextensions'] = 'View {$a} user extensions'; $string['viewmysubmission'] = 'View my submission'; $string['viewsubmissions'] = 'View {$a} submitted assignments'; $string['yoursubmission'] = 'Your submission'; diff -Naur moodle2.2_ori//mod/assignment/lib.php moodle2.2//mod/assignment/lib.php --- moodle2.2_ori//mod/assignment/lib.php 2012-03-10 05:34:53.000000000 +0530 +++ moodle2.2//mod/assignment/lib.php 2012-04-07 12:57:51.000000000 +0530 @@ -46,9 +46,11 @@ */ class assignment_base { - const FILTER_ALL = 0; - const FILTER_SUBMITTED = 1; - const FILTER_REQUIRE_GRADING = 2; + const FILTER_ALL = 0; + const FILTER_SUBMITTED = 1; + const FILTER_REQUIRE_GRADING = 2; + const FILTER_EXTENDED = 3; + const FILTER_REQUIRE_EXTENSION = 4; /** @var object */ var $cm; @@ -213,6 +215,31 @@ echo $OUTPUT->box_end(); echo plagiarism_print_disclosure($this->cm->id); } + /** + * Display the assignment dates + * + * Prints the assignment start and end dates in a box. + * This will be suitable for most assignment types + */ + function view_default_dates() + { + global $OUTPUT; + if (!$this->assignment->timeavailable && !$this->assignment->timedue) { + return; + } + echo $OUTPUT->box_start('generalbox boxaligncenter', 'dates'); + echo ''; + if ($this->assignment->timeavailable) { + echo ''; + echo ' '; + } + if ($this->assignment->timedue) { + echo ''; + echo ' '; + } + echo '
'.get_string('availabledate','assignment').':'.userdate($this->assignment->timeavailable).'
'.get_string('duedate','assignment').':'.userdate($this->assignment->timedue).'
'; + echo $OUTPUT->box_end(); + } /** * Display the assignment dates @@ -225,7 +252,12 @@ if (!$this->assignment->timeavailable && !$this->assignment->timedue) { return; } - + $extension=$this->get_extension(); + $extensiontime = false; + if ($extension) { + $extensiontime = empty($extension->extension) ? false : $extension->extension; + $comment = $extension->extensioncomment; + } echo $OUTPUT->box_start('generalbox boxaligncenter', 'dates'); echo ''; if ($this->assignment->timeavailable) { @@ -234,10 +266,22 @@ } if ($this->assignment->timedue) { echo ''; - echo ' '; + if ($extensiontime) { + echo ' + '; + } else { + echo ''; + } } echo '
'.get_string('duedate','assignment').':'.userdate($this->assignment->timedue).'
'.userdate($extension->extension).'
Extension: '.format_time($extension->extension - $this->assignment->timedue).'
'.userdate($this->assignment->timedue).'
'; echo $OUTPUT->box_end(); + echo ''; + if ($this->assignment->preventlate && $this->assignment->timedue) { + if ($extension && !empty($extension->extension) && !empty($extension->extensioncomment)) { + $comment=$OUTPUT->notification($comment, 'warning'); + echo $comment; + } + } } @@ -402,10 +446,15 @@ if ($submission = $this->get_submission($USER->id)) { // If the submission has been completed if ($this->is_submitted_with_required_data($submission)) { - if ($submission->timemodified <= $this->assignment->timedue || empty($this->assignment->timedue)) { - $submitted = ''.userdate($submission->timemodified).''; + if ($this->assignment->preventlate && $this->assignment->timedue) { + if ($extension = $this->has_extension($USER->id)) { + //$userextension = assignment_display_extension($extension, $submission->timemodified, $this->assignment->timedue); + $submitted = '' .userdate($submission->timemodified).''; + } + } else if ($submission->timemodified <= $this->assignment->timedue || empty($this->assignment->timedue)) { + $submitted = ''.userdate($submission->timemodified).''; } else { - $submitted = ''.userdate($submission->timemodified).''; + $submitted = ''.userdate($submission->timemodified).''; } } } @@ -1057,7 +1106,14 @@ $mformdata->teacher = $teacher; $mformdata->assignment = $assignment; $mformdata->submission = $submission; - $mformdata->lateness = $this->display_lateness($submission->timemodified); + if ($assignment->preventlate && $assignment->timedue) { + if ($extension = $this->has_extension($userid)) { + $userextension = assignment_display_extension($extension, $submission->timemodified, $assignment->timedue); + $mformdata->extension = $userextension; + } + } else { + $mformdata->lateness = $this->display_lateness($submission->timemodified); + } $mformdata->auser = $auser; $mformdata->user = $user; $mformdata->offset = $offset; @@ -1442,7 +1498,12 @@ if ($auser->timemodified > 0) { $studentmodifiedcontent = $this->print_student_answer($auser->id) . userdate($auser->timemodified); - if ($assignment->timedue && $auser->timemodified > $assignment->timedue) { + if ($assignment->preventlate && $assignment->timedue) { + if ($extension = $this->has_extension($auser->id)) { + $studentmodifiedcontent .= assignment_display_extension($extension, $auser->timemodified,$assignment->timedue); + $rowclass = 'sfextension'; + } + } else if ($assignment->timedue && $auser->timemodified > $assignment->timedue) { $studentmodifiedcontent .= assignment_display_lateness($auser->timemodified, $assignment->timedue); $rowclass = 'late'; } @@ -2138,7 +2199,13 @@ function isopen() { $time = time(); if ($this->assignment->preventlate && $this->assignment->timedue) { - return ($this->assignment->timeavailable <= $time && $time <= $this->assignment->timedue); + $extension = $this->get_extension(); + if ($extension && !empty($extension->extension)) { + $timedue = $extension->extension; + } else { + $timedue = $assignment->timedue; + } + return ($this->assignment->timeavailable <= $time && $time <= $timedue); } else { return ($this->assignment->timeavailable <= $time); } @@ -2390,6 +2457,756 @@ return true; } + function has_extension($userid = 0) { + if (empty($userid)) { + $userid= $USER->id; + } + if ($extension = $this->get_extension($userid)) { + return $extension ; + } + return false; + } + /* + * extension link to be displayed who have capability to give extension + * + */ + function extension_link() { + global $USER, $CFG; + $extensionlink = ''; + $urlbase = "{$CFG->wwwroot}/mod/assignment/"; + $context = get_context_instance(CONTEXT_MODULE,$this->cm->id); + if (has_capability('mod/assignment:individualextension', $context)) { + if ($count = $this->count_real_extensions()) { + $extensionlink = ''. + get_string('viewextensions', 'assignment', $count).''; + } else { + $extensionlink = ''. + get_string('noextended', 'assignment').''; + } + } + return $extensionlink; + } + + /** + * Load the extension object for a particular user + * @global object + * @param $userid int The id of the user whose extension we want or 0 in which case USER->id is used + * @param $createnew boolean optional Defaults to false. If set to true a new extension object will be created in the database + * @return object The extension + */ + function get_extension($userid = 0, $createnew = false) { + global $USER, $DB; + if (empty($userid)) { + $userid = $USER->id; + } + $extension = $DB->get_record('assignment_extensions', array('assignmentid' => $this->assignment->id , 'userid' => $userid)); + if ($extension || !$createnew){ + return $extension; + } + $newextension = $this->prepare_new_extension($userid); + $DB->insert_record('assignment_extensions', $newextension); + $extension = $DB->get_record('assignment_extensions', array('assignmentid' => $this->assignment->id , 'userid' => $userid)); + return $extension; + } +/** + * Instantiates a new extension object for a given user + * + * Sets the assignment, userid and times, everything else is set to default values. + * + * @param int $userid The userid for which we want a extension object + * @return object The extension + */ + function prepare_new_extension($userid) { + global $USER; + $extension = new stdclass(); + $extension->assignmentid = $this->assignment->id; + $extension->userid = $userid; + $extension->extensioncomment = ''; + $extension->timegiven = 0; + $extension->timemodified = 0; + $extension->extension = 0; + $extension->teacher = 0; + $extension->final=0; + return $extension; + } + /* + * Count real extension given to users + * + */ + function count_real_extensions() { + global $CFG, $DB; + $context = get_context_instance(CONTEXT_MODULE, $this->cm->id); + // Get ids of users enrolled in the given course. + list($enroledsql, $params) = get_enrolled_sql($context, 'mod/assignment:view'); + $params['assignmentid'] = $this->cm->instance; + // Get ids of users enrolled in the given course. + return $DB->count_records_sql("SELECT COUNT('x') + FROM {assignment_extensions} ae + LEFT JOIN {assignment} a ON a.id = ae.assignmentid + INNER JOIN ($enroledsql) u ON u.id = ae.userid + WHERE ae.assignmentid = :assignmentid AND + ae.extension > 0", $params); + } + /** + * process teacher extension to the student + * This is called form extensions() when extension has taken place + * It gets data from submitted form. + * + * @global + * @return object|bool the updated extension object or false + */ + + + function process_extension() + { + global $CFG, $USER, $DB; + if (!$feedback = data_submitted() or !confirm_sesskey()) { + return false; + } + if ((int)$feedback->saveuserid !== -1) { + $feedback->userid = $feedback->saveuserid; + } + if (!empty($feedback->cancel)) { + return false; + } + $newextension = $this->get_extension($feedback->userid, true); + $updatedb=false; + //if (isset($feedback->extension)) { + $stime = $feedback->extension; + $submitextensiondate=make_timestamp($stime['year'], $stime['month'], $stime['day'], $stime['hour'], $stime['minute']); + if ($submitextensiondate > $this->assignment->timedue && $submitextensiondate != $newextension->extension) { + $newextension->extension = $submitextensiondate ; + $updatedb = true; + } + else { + unset($newextension->extension); + } + //} + $excomment = $feedback->extensioncomment_editor['text']; + if (!empty($excomment) && ($excomment != $newextension->extensioncomment)) { + $newextension->extensioncomment=$excomment; + $updatedb = true; + } + else { + unset($newextension->extensioncomment); + } + if (!empty($feedback->final)) { + $newextension->final = 1; + $updatedb = true; + } + $newextension->timemodified = time(); + if (empty($newextension->timegiven)) { + $newextension->timegiven = time(); + } + $newextension->teacher = $USER->id; + if ($updatedb) { + $DB->update_record('assignment_extensions', $newextension); + add_to_log($this->course->id, 'assignment', 'update extension', 'extensions.php?id='.$this->cm->id.'&user='.$feedback->userid, + $feedback->userid, $this->cm->id); + return $newextension; + } + return false; + + } + /** + * Display a single extension, ready for extension on a popup window + * + * This default method prints the student info, assignment dates, default extension as timedue and extensioncomment box at the top + * teacher info at the bottom. + * This method also fetches the necessary data in order to be able to + * provide a "Next extension" button. + * This method gets its arguments from the page parameters userid and offset + * + * @global object + * @global object + * @param string $extra_javascript + */ + function display_extension($offset = -1, $userid = -1, $display = true) { + global $CFG, $USER, $COURSE, $PAGE, $OUTPUT, $DB; + require_once("$CFG->libdir".'/tablelib.php'); + if ($userid == -1) { + $userid = required_param('userid', PARAM_INT); + } + if ($offset == -1) { + $offset = required_param('offset', PARAM_INT); + } + $filter = optional_param('filter', 0, PARAM_INT); + if (!$user = $DB->get_record('user', array('id' => $userid))) { + print_error("nousers"); + } + $course = $this->course; + $assignment = $this->assignment; + $cm = $this->cm; + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + $PAGE->set_title($this->course->fullname . ': ' .get_string('extensions', 'assignment').' - '.fullname($user, true)); + $PAGE->set_heading($this->course->fullname); + $PAGE->navbar->add(get_string('extension','assignment'), new moodle_url('/mod/assignment/extensions.php', array('id'=>$cm->id))); + $PAGE->navbar->add(fullname($user, true)); + + echo $OUTPUT->header(); + echo $OUTPUT->heading(get_string('extension', 'assignment').': '.fullname($user, true)); + if ($assignment->preventlate && $assignment->timedue) { + + if (!$extension = $this->get_extension($user->id)) { + $extension = $this->prepare_new_extension($user->id); + } + $currentgroup = groups_get_activity_group($cm); + $users = get_enrolled_users($context, 'mod/assignment:submit', $currentgroup, 'u.id'); + if ($users) { + $users = array_keys($users); + // if groupmembersonly used, remove users who are not in any group + if (!empty($CFG->enablegroupmembersonly) and $cm->groupmembersonly) { + if ($groupingusers = groups_get_grouping_members($cm->groupingid, 'u.id', 'u.id')) { + $users = array_intersect($users, array_keys($groupingusers)); + } + } + } + $nextid = 0; + $where = ''; + if($filter == self::FILTER_EXTENDED) { + $where .= 'ae.extension >'. $this->assignment->timedue .' AND '; + } + else if($filter == self::FILTER_REQUIRE_EXTENSION) { + $where .= ' ae.extension = 0 AND '; + } + if ($users) { + $userfields = user_picture::fields('u'); + $select = 'SELECT ' . $userfields .', ae.id AS extensionid, ae.extension, ae.timemodified, ae.timegiven, + ae.extensioncomment, ae.teacher, ae.final, + CASE WHEN ae.extension > 0 AND ae.extension >'. $this->assignment->timedue .' THEN 1 ELSE 0 END AS status '; + + $sql = 'FROM {user} u '. + 'LEFT JOIN {assignment_extensions} ae ON u.id = ae.userid + AND ae.assignmentid = '.$this->assignment->id.' '. + 'WHERE '.$where.'u.id IN ('.implode(',', $users).') '; + + if ($sort = flexible_table::get_sort_for_table('mod-assignment-extensions')) { + $sort = 'ORDER BY '.$sort.' '; + } + $auser = $DB->get_records_sql($select.$sql.$sort, null, $offset, 2); + if (is_array($auser) && count($auser)>1) { + $nextuser = next($auser); + $nextid = $nextuser->id; + } + } + if ($extension->teacher) { + $teacher = $DB->get_record('user', array('id'=>$extension->teacher)); + } + else { + global $USER; + $teacher = $USER; + } + + $mformdata = new stdClass(); + $mformdata->context = $this->context; + // $mformdata->courseid = $this->course->id; + $mformdata->context = $this->context; + $mformdata->maxbytes = $this->course->maxbytes; + $mformdata->teacher = $teacher; + $mformdata->assignment = $assignment; + $mformdata->extension = $extension; + $mformdata->auser = $auser; + $mformdata->user = $user; + $mformdata->offset = $offset; + $mformdata->userid = $userid; + $mformdata->cm = $this->cm; + $mformdata->nextid = $nextid; + $mformdata->extensioncomment= $extension->extensioncomment; + $mformdata->extensioncommentformat= FORMAT_HTML; + $mformdata->filter = $filter; + $extendform= new mod_assignment_extensions_form(null,$mformdata); + + if (!$display) { + return $mformdata; + } + + if ($extendform->is_cancelled()) { + redirect('extensions.php?id='.$this->cm->id); + } + + + // display actual form here + $extendform->display(); + } else { + $this->view_default_dates(); + echo $OUTPUT->box_start('generalbox boxaligncenter', 'noexrequired'); + echo html_writer::tag('div', get_string('noextensionrequired', 'assignment'), array('class' => 'nodisplay')); + echo $OUTPUT->box_end(); + } + + echo $OUTPUT->footer(); // display footer here + + } + /** + * Top-level function for handling of extensions called by extensions.php + * + * This is for handling the teacher interaction with the extension interface + * This should be suitable for most assignment types. + * + * @global object + * @param string $mode Specifies the kind of teacher interaction taking place + */ + function extensions($mode) { + global $USER, $DB, $OUTPUT, $PAGE; + if (optional_param('next', null, PARAM_BOOL)) { + $mode = 'next'; + } + if (optional_param('saveandnext', null, PARAM_BOOL)) { + $mode = 'saveandnext'; + } + switch ($mode) { + case 'extend': // We are in a main window extension + if ($extension = $this->process_extension()) { + $message = $OUTPUT->notification(get_string('changessaved'), 'notifysuccess'); + $this->display_extensions($message); + }else { + $this->display_extensions(); + } + break; + case 'single': // We are in a main window displaying one extension + if ($extension = $this->process_extension()) { + $message = $OUTPUT->notification(get_string('changessaved'), 'notifysuccess'); + $this->display_extensions($message); + } else { + $this->display_extension(); + } + break; + case 'all': // Main window, display everything + $this->display_extensions(); + break; + case 'fastextend': + ///do the fast extension stuff - this process should work for all 3 subclasses + $extensions = false; + $commenting = false; + $col = false; + if (isset($_POST['extensioncomment'])) { + $col = 'extensioncomment'; + $commenting = true; + } + if (isset($_POST['extension'])) { + $col = 'extension'; + $extensions = true; + } + if (!$col) { + // both extension and comment columns were collapsed + $this->display_extensions(); + break; + } + if (!$formdata = data_submitted() or !confirm_sesskey()) { + break; + } + foreach( $_POST[$col] as $id => $unusedvalue) { + $id = (int)$id; + if (!$extension = $this->get_extension($id)) { + $extension = $this->prepare_new_extension($id); + $newextension = true; + }else { + $newextension = false; + } + $updatedb = false; + if ($extensions) { + $stime = $_POST['extension'][$id]; + $submit_extension = make_timestamp($stime['year'], $stime['month'], $stime['day'], $stime['hour'], $stime['minute']); + if ($submit_extension > $this->assignment->timedue && ($submit_extension != $extension->extension)) { + $extension->extension = $submit_extension; + $updatedb = true; + } + $extension->finalextension = empty($extension->extension) ? 0 : userdate($extension->extension - $assignment->timedue); + }else { + if (!$newextension) { + unset($extension->extension); // Don't need to update this. + unset($extension->finalextension); + } + } + if ($commenting) { + $commentvalue = trim($_POST['extensioncomment'][$id]); + $updatedb = $updatedb || ($extension->extensioncomment != $commentvalue); + $extension->extensioncomment = $commentvalue; + }else { + if (!$newextension) { + unset($extension->extensioncomment); // Don't need to update this. + } + } + $extension->teacher = $USER->id; + if ($newextension) { + $extension->timegiven = time(); + } + if ($newextension) { + $extension->timegiven = time(); + } + $extension->timemodified = time(); + if ($updatedb) { //update the database + if ($newextension) { + if (!isset($extension->extensioncomment)) { + $extension->extensioncomment = ''; + } + $eid = $DB->insert_record('assignment_extensions', $extension); + $extension->id = $eid; + }else { + $DB->update_record('assignment_extensions', $extension); + } + add_to_log($this->course->id, 'assignment', 'update grades', + 'extensions.php?id='.$this->cm->id.'&user='.$extension->userid, + $extension->userid, $this->cm->id); + } + } + $message = $OUTPUT->notification(get_string('changessaved'), 'notifysuccess'); + $this->display_extensions($message); + break; + case 'saveandnext': + //We are in pop up. save the current one and go to the next one. + //first we save the current changes + if ($extension = $this->process_extension()) { + + } + case 'next': + /// We are currently in pop up, but we want to skip to next one without saving. + /// This turns out to be similar to a single case + /// The URL used is for the next extensionsion. + $offset = required_param('offset', PARAM_INT); + $nextid = required_param('nextid', PARAM_INT); + $id = required_param('id', PARAM_INT); + $filter = optional_param('filter', self::FILTER_ALL, PARAM_INT); + $redirect = new moodle_url('extensions.php', + array('id' => $id, 'offset' => $offset, 'userid' => $nextid, + 'mode' => 'single', 'filter' => $filter)); + redirect($redirect); + break; + case 'singlenosave': + $this->display_extension(); + break; + default: + echo "Something seriously wrong happened !!"; + break; + } + + } + /** + * Display all the extensions ready for extension + * + * @global object + * @global object + * @global object + * @global object + * @param string $message + * @return bool|void + */ + function display_extensions($message='') { + global $CFG, $DB, $USER, $DB, $OUTPUT, $PAGE; + /* first we check to see if the form has just been submitted + * to request user_preference updates + */ + $filters = array( self::FILTER_ALL => get_string('all'), + self::FILTER_EXTENDED =>get_string('extended','assignment'), + self::FILTER_REQUIRE_EXTENSION => get_string('requireextension', 'assignment') + ); + $updatepref = optional_param('updatepref', 0, PARAM_BOOL); + if ($updatepref) { + $perpage = optional_param('perpage', 10, PARAM_INT); + $perpage = ($perpage <= 0) ? 10 : $perpage ; + $filter = optional_param('filter', 0, PARAM_INT); + set_user_preference('extensions_perpage', $perpage); + set_user_preference('extensions_quickextend', optional_param('quickextend', 0, PARAM_BOOL)); + set_user_preference('extensions_filter', $filter); + } + /* next we get perpage and quickextend (allow quick extend) params + * from database + */ + $perpage = get_user_preferences('extensions_perpage', 10); + $quickextend = get_user_preferences('extensions_quickextend', 0); + $filter = get_user_preferences('extensions_filter', 0); + $page = optional_param('page', 0, PARAM_INT); + // some shortcuts + $course = $this->course; + $assignment = $this->assignment; + $cm = $this->cm; + $tabindex = 1; + add_to_log($course->id, 'assignment', 'view extension', 'extensions.php?id='.$this->cm->id, $this->assignment->id, $this->cm->id); + $PAGE->set_title(format_string($this->assignment->name,true)); + $PAGE->set_heading($this->course->fullname); + echo $OUTPUT->header(); + $this->view_default_dates(); + if (!empty($assignment->preventlate) && !empty($assignment->timedue)) { // assignment is open as preventlate or timedue is not set + echo '
'; + if (!empty($message)) { + echo $message; + } + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + $groupmode = groups_get_activity_groupmode($cm); + $currentgroup = groups_get_activity_group($cm, true); + if ($quickextend) { + $formattrs = array(); + $formattrs['action'] = new moodle_url('/mod/assignment/extensions.php'); + $formattrs['id'] = 'faste'; + $formattrs['method'] = 'post'; + echo html_writer::start_tag('form', $formattrs); + echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'id', 'value'=> $this->cm->id)); + echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'mode', 'value'=> 'fastextend')); + echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'page', 'value'=> $page)); + echo html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'sesskey', 'value'=> sesskey())); + } + /// Get all ppl that are allowed to submit assignments + list($esql, $params) = get_enrolled_sql($context, 'mod/assignment:submit', $currentgroup); + if ($filter == self::FILTER_ALL) { + $sql = "SELECT u.id FROM {user} u ". + "LEFT JOIN ($esql) eu ON eu.id=u.id ". + "WHERE u.deleted = 0 AND eu.id=u.id "; + } else { + $wherefilter = ' AND ae.assignmentid = '. $this->assignment->id; + $assignmentextension = "LEFT JOIN {assignment_extensions} ae ON (u.id = ae.userid)"; + if($filter == self::FILTER_EXTENDED) { + $wherefilter .= ' AND ae.extension > '.$assignment->timedue ; + } else if($filter == self::FILTER_REQUIRE_EXTENSION) { + $wherefilter .= ' AND ae.extension = 0 '; + } else { + $assignmentextension = ""; + $wherefilter = ""; + } + $sql = "SELECT u.id FROM {user} u ". + "LEFT JOIN ($esql) eu ON eu.id=u.id ". + $assignmentextension. + " WHERE u.deleted = 0 AND eu.id=u.id ". + $wherefilter; + } + $users = $DB->get_records_sql($sql, $params); + $users = array_keys($users); + if ($users and !empty($CFG->enablegroupmembersonly) and $cm->groupmembersonly) { + if ($groupingusers = groups_get_grouping_members($cm->groupingid, 'u.id', 'u.id')) { + $users = array_intersect($users, array_keys($groupingusers)); + } + } + $extrafields = get_extra_user_fields($context); + $tablecolumns = array_merge(array('picture', 'fullname'), $extrafields, + array( 'extension' ,'extensioncomment', 'status', 'finalextension')); + $extrafieldnames = array(); + foreach ($extrafields as $field) { + $extrafieldnames[] = get_user_field_name($field); + } + $tableheaders = array_merge( + array('', get_string('fullnameuser')), + $extrafieldnames, + array( + get_string('extension', 'assignment'), + get_string('extensioncomment', 'assignment'), + get_string('status'), + get_string('finalextension', 'assignment'), + ) + ); + require_once($CFG->libdir.'/tablelib.php'); + $table = new flexible_table('mod-assignment-extensions'); + $table->define_columns($tablecolumns); + $table->define_headers($tableheaders); + $table->define_baseurl($CFG->wwwroot.'/mod/assignment/extensions.php?id='.$this->cm->id.'&currentgroup='.$currentgroup); + $table->sortable(true, 'lastname');//sorted by lastname by default + $table->collapsible(true); + $table->initialbars(true); + $table->column_suppress('picture'); + $table->column_suppress('fullname'); + $table->column_class('picture', 'picture'); + $table->column_class('fullname', 'fullname'); + foreach ($extrafields as $field) { + $table->column_class($field, $field); + } + $table->column_class('extension', 'extension'); + $table->column_class('extensioncomment', 'extensioncomment'); + $table->column_class('status', 'status'); + $table->column_class('finalextension', 'finalextension'); + $table->set_attribute('cellspacing', '0'); + $table->set_attribute('id', 'attempts'); + $table->set_attribute('class', 'extensions'); + $table->set_attribute('width', '100%'); + $table->no_sorting('finalextension'); + // Start working -- this is necessary as soon as the niceties are over + $table->setup(); + list($where, $params) = $table->get_sql_where(); + if ($where) { + $where .= ' AND '; + } + if ($filter == self::FILTER_EXTENDED) { + $where .= 'ae.timemodified > 0 AND ae.extension >' .$assignment->timedue .' AND '; + } else if ($filter == self::FILTER_REQUIRE_EXTENSION) { + $where .= ' ae.extension = 0 AND '; + } + if ($sort = $table->get_sql_sort()) { + $sort = ' ORDER BY '.$sort; + } + $ufields = user_picture::fields('u', $extrafields); + if (!empty($users)) { + $select = "SELECT $ufields, + ae.id AS extensionid, ae.extension, ae.timegiven, ae.timemodified, + ae.extensioncomment, ae.teacher, ae.final , + CASE WHEN ae.extension > 0 AND ae.extension > $assignment->timedue THEN 1 ELSE 0 END AS status "; + + $sql = 'FROM {user} u '. + 'LEFT JOIN {assignment_extensions} ae ON u.id = ae.userid + AND ae.assignmentid = '.$this->assignment->id.' '. + ' WHERE '.$where.' u.id IN ('.implode(',',$users).')' ; + + $ausers = $DB->get_records_sql($select.$sql.$sort, $params, $table->get_page_start(), $table->get_page_size()); + $table->pagesize($perpage, count($users)); + ///offset used to calculate index of student in that particular query, needed for the pop up to know who's next + $offset = $page * $perpage; + $currentposition = 0; + $endposition = $offset + $perpage; + if ($ausers !== false) { + foreach ($ausers as $auser) { + if ($currentposition == $offset && $offset < $endposition) { + $rowclass = null; + $picture = $OUTPUT->user_picture($auser); + $buttonlink = false; + if (empty($auser->final)) { + $buttonlink = true; + if ($quickextend) { + require_once("$CFG->libdir".'/form/datetimeselector.php'); + $dateselector = new MoodleQuickForm_date_time_selector('extension['.$auser->id .']', + get_string('extension', 'assignment')); + if (empty($auser->extensionid)) { + $extensiontime = $assignment->timedue; + $currentdate = usergetdate($extensiontime); + // Round minutes to the previous multiple of step. + $currentdate['minutes'] -= $currentdate['minutes'] % $dateselector->_options['step']; + $value = array( + 'minute' => $currentdate['minutes'], + 'hour' => $currentdate['hours'], + 'day' => $currentdate['mday'], + 'month' => $currentdate['mon'], + 'year' => $currentdate['year'] + ); + if (null !== $value) { + $dateselector->setValue($value); + } + $extension = $dateselector->toHtml(); + $extension = html_writer::tag('div', $extension, array('id' => 'ex'.$auser->id)); + $finalextension = ' '; + $finalextension = html_writer::tag('div',$finalextension,array('id' => 'fe' .$auser->id)); + $comment = '
' + . '
'; + } else if (!empty($auser->extensionid)) { + $extensiontime = (empty($auser->extension) ? $assignment->timedue : $auser->extension); + $currentdate = usergetdate($extensiontime); + // Round minutes to the previous multiple of step. + $currentdate['minutes'] -= $currentdate['minutes'] % $dateselector->_options['step']; + $value = array( + 'minute' => $currentdate['minutes'], + 'hour' => $currentdate['hours'], + 'day' => $currentdate['mday'], + 'month' => $currentdate['mon'], + 'year' => $currentdate['year']); + if (null !== $value) { + $dateselector->setValue($value); + } + $extension = $dateselector->toHtml(); + $extension = html_writer::tag('div', $extension, array('id' => 'ex'.$auser->id)); + if (!empty($auser->extension)) { + $actualextension = $auser->extension - $assignment->timedue; + $finalextension = format_time($actualextension);// get user display extension time + $finalextension = html_writer::tag('div', $finalextension, array('id' => 'fe'.$auser->id)); + } else { + $finalextension = html_writer::tag('div', ' ', array('id' => 'fe'.$auser->id)); + } + $comment = '
' + . '
'; + } + } else { // without quick extend + if (!empty($auser->extensionid) && !empty($auser->extension)) { + $extension = userdate($auser->extension); + $extension = html_writer::tag('div', $extension, array('id' => 'ex'.$auser->id)); + $actualextension = $auser->extension - $assignment->timedue; + $finalextension = format_time($actualextension); + $finalextension = html_writer::tag('div', $finalextension, array('id' => 'fe'.$auser->id)); + } else { + $extension = html_writer::tag('div',' ', array('id' => 'ex'.$auser->id)) ; + $finalextension = html_writer::tag('div', ' ', array('id' => 'fe'.$auser->id)); + } + if (!empty($auser->extensioncomment)) { + $comment = '
'.shorten_text(strip_tags($auser->extensioncomment),40).'
'; + } else { + $comment = html_writer::tag('div', ' ', array('id' => 'ec'.$auser->id)); + } + } + } else { // without final extension + $etime = empty($auser->extension) ? 0 : $auser->extension; + $displaydate = empty($etime) ? ' ' : userdate($auser->extension); + $extension = html_writer::tag('div', $displaydate, array('id' => 'ex'.$auser->id)); + $dcomment = empty($auser->extensioncomment) ? ' ' : shorten_text(strip_tags($auser->extensioncomment),40); + $comment = '
'.$dcomment.'
'; + $finalextension = empty($auser->extension) ? ' ' : format_time($auser->extension - $assignment->timedue); + $finalextension = html_writer::tag('div', $finalextension, array('id' => 'fe'.$auser->id)); + $buttonlink = false; + } + if ($buttonlink) { + if (empty($auser->status)) { /// Confirm we have exclusively 0 or 1 + $auser->status = 0; + } else { + $auser->status = 1; + } + $strupdate=get_string('update'); + $strextend=get_string('extend', 'assignment'); + $buttontext = ($auser->status == 1) ? $strupdate : $strextend; + $popup_url = '/mod/assignment/extensions.php?id='.$this->cm->id + . '&userid='.$auser->id.'&mode=single'.'&filter='.$filter.'&offset='.$offset; + $button = $OUTPUT->action_link($popup_url, $buttontext); + $status = '
'.$button.'
'; + } else { + $status = html_writer::tag('div', ' ', array('id' => 'eb'.$auser->id)); + } + $offset++; + $userlink = '' . + fullname($auser, has_capability('moodle/site:viewfullnames', $this->context)) . ''; + $extradata = array(); + foreach ($extrafields as $field) { + $extradata[] = $auser->{$field}; + } + $row = array_merge(array($picture, $userlink), $extradata, + array($extension,$comment, $status, $finalextension)); + $table->add_data($row, $rowclass); + } + $currentposition++; + } + } + $table->print_html(); /// Print the whole table + } else { + if ($filter == self::FILTER_EXTENDED) { + echo html_writer::tag('div', get_string('noextended', 'assignment'), array('class' => 'nodisplay')); + } else if ($filter == self::FILTER_REQUIRE_EXTENSION) { + echo html_writer::tag('div', get_string('norequireextension', 'assignment'), array('class' => 'nodisplay')); + } + } + if ($quickextend && $table->started_output && !empty($users)) { + $savefeedback = html_writer::empty_tag('input', array('type' => 'submit', 'name' => 'faste', + 'value' => get_string('saveallextensions', 'assignment'))); + echo html_writer::tag('div', $savefeedback, array('class' => 'fastebutton')); + echo html_writer::end_tag('form'); + } else if ($quickextend) { + echo html_writer::end_tag('form'); + } + echo '
'; + /// End of fast extension form + /// Mini form for setting user preference + $formaction = new moodle_url('/mod/assignment/extensions.php', array('id' => $this->cm->id)); + $mform = new MoodleQuickForm('optionspref', 'post', $formaction, '', array('class' => 'optionspref')); + $mform->addElement('hidden', 'updatepref'); + $mform->setDefault('updatepref' , 1); + $mform->addElement('header', 'qeprefs', get_string('optionalsettings', 'assignment')); + $mform->addElement('select', 'filter', get_string('show'), $filters); + $mform->setDefault('filter', $filter); + $mform->addElement('text', 'perpage', get_string('epagesize', 'assignment'), array('size' => 1)); + $mform->setDefault('perpage', $perpage); + $mform->addElement('checkbox', 'quickextend', get_string('quickextend', 'assignment')); + $mform->setDefault('quickextend', $quickextend); + $mform->addElement('submit', 'savepreferences', get_string('savepreferences')); + $mform->display(); + } else { // preventlate or timedue is not set. + echo $OUTPUT->box_start('generalbox boxaligncenter', 'noexrequired'); + echo html_writer::tag('div', get_string('noextensionrequired', 'assignment'), array('class' => 'nodisplay')); + echo $OUTPUT->box_end(); + } + echo $OUTPUT->footer(); + } + + } ////// End of the assignment_base class @@ -2427,11 +3244,15 @@ $mform->setType('saveuserid', PARAM_INT); $mform->addElement('hidden', 'filter', "0"); $mform->setType('filter', PARAM_INT); - + if (isset($this->_customdata->extension)) { + $extensionorlateness = $this->_customdata->extension; + } else { + $extensionorlateness = $this->_customdata->lateness; + } $mform->addElement('static', 'picture', $OUTPUT->user_picture($this->_customdata->user), fullname($this->_customdata->user, true) . '
' . userdate($this->_customdata->submission->timemodified) . - $this->_customdata->lateness ); + $extensionorlateness ); $this->add_submission_content(); $this->add_grades_section(); @@ -2647,6 +3468,122 @@ return $data; } } +class mod_assignment_extensions_form extends moodleform { + function definition() { + global $OUTPUT; + $mform =& $this->_form; + $formattr = $mform->getAttributes(); + $formattr['id'] = 'extensionform'; + $mform->setAttributes($formattr); + // hidden params + $mform->addElement('hidden', 'offset', ($this->_customdata->offset+1)); + $mform->setType('offset', PARAM_INT); + $mform->addElement('hidden', 'userid', $this->_customdata->userid); + $mform->setType('userid', PARAM_INT); + $mform->addElement('hidden', 'nextid', $this->_customdata->nextid); + $mform->setType('nextid', PARAM_INT); + $mform->addElement('hidden', 'id', $this->_customdata->cm->id); + $mform->setType('id', PARAM_INT); + $mform->addElement('hidden', 'sesskey', sesskey()); + $mform->setType('sesskey', PARAM_ALPHANUM); + $mform->addElement('hidden', 'mode', 'extend'); + $mform->setType('mode', PARAM_TEXT); + $mform->addElement('hidden', 'menuindex', "0"); + $mform->setType('menuindex', PARAM_INT); + $mform->addElement('hidden', 'saveuserid', "-1"); + $mform->setType('saveuserid', PARAM_INT); + $mform->addElement('hidden', 'filter', "0"); + $mform->setType('filter', PARAM_INT); + $mform->addElement('static', 'picture', $OUTPUT->user_picture($this->_customdata->user), + fullname($this->_customdata->user, true) . '
' + ); + $this->view_assignment_dates(); + $this->add_extension_content(); + $this->add_extension_comment(); + if (empty($this->_customdata->extension->final)) { + $mform->addElement('header','lastextension', get_string('finalextension','assignment')); + $ynoptions = array( 0 => get_string('no'), 1 => get_string('yes')); + $mform->addElement('select', 'final', get_string('finalextension', 'assignment'), $ynoptions); + $mform->setDefault('final', 0); + } + if (!empty($this->_customdata->extension->timemodified)) { + $datestring = userdate($this->_customdata->extension->timemodified) ."  (".format_time(time() - $this->_customdata->extension->timemodified).")"; + $mform->addElement('header', 'Last Extend', get_string('lastextended', 'assignment')); + $mform->addElement('static', 'picture', $OUTPUT->user_picture($this->_customdata->teacher) , + fullname($this->_customdata->teacher,true). + '
'.$datestring); + } + $this->add_action_buttons(); + } + + function view_assignment_dates() { + global $OUTPUT; + $mform =& $this->_form; + $mform->addElement('header','fdates',get_string('assignmentdates','assignment')); + if (!$this->_customdata->assignment->timeavailable && !$this->_customdata->assignment->timedue) { + return ; + } + $dates = '_customdata->assignment->timeavailable) { + $mform->addElement('static','availabledate',get_string('availabledate', 'assignment').':',userdate($this->_customdata->assignment->timeavailable)); + } + if ($this->_customdata->assignment->timedue) { + $mform->addElement('static','duedate',get_string('duedate', 'assignment').':',userdate($this->_customdata->assignment->timedue)); + } + + + } + + function add_extension_content() { + $mform =& $this->_form; + $mform->addElement('header','Extension',get_string('extension','assignment')); + if (empty($this->_customdata->extension->final)) { + $mform->addElement('date_time_selector','extension', get_string('extend', 'assignment')); + if (!empty($this->_customdata->extension->extension)) { + $mform->setDefault('extension',$this->_customdata->extension->extension); + } else { + $mform->setDefault('extension',$this->_customdata->assignment->timedue); + } + $mform->addElement('static','hint', '*Hint:', 'Extension datetime should be greater than due date.'); + } else { + $date_or_text=empty($this->_customdata->extension->extension) ? ' ' + : userdate($this->_customdata->extension->extension); + $mform->addElement('static','extension_date',get_string('finalextension', 'assignment').' :',$date_or_text); + } + } + + function add_extension_comment() { + global $OUTPUT; + $mform =& $this->_form; + $context=$this->_customdata->context; + $mform->addElement('header', 'FeedBack', get_string('feedback', 'assignment')); + if (empty($this->_customdata->extension->final)) { + $mform->addElement('editor', 'extensioncomment_editor', get_string('feedback', 'assignment').":", + null, array('context' => $context))->setValue(array('text' => $this->_customdata->extensioncomment)); + /*$mform->setType('extensioncomment_editor', PARAM_RAW); // to be cleaned before display + $mform->setDefault('extensioncomment_editor',$this->_customdata->extensioncomment);*/ + } else { + $mform->addElement('static', 'comment',get_string('feedback', 'assignment') .':', $this->_customdata->extensioncomment); + } + } + + function add_action_buttons() { + $mform =& $this->_form; + $final = $this->_customdata->extension->final; + $buttonarray=array(); + if (!$final) { + $buttonarray[] = &$mform->createElement('submit', 'submitbutton', get_string('savechanges')); + $buttonarray[] = &$mform->createElement('submit', 'saveandnext', get_string('saveandnext')); + } + if ($this->_customdata->nextid > 0) { + $buttonarray[] = &$mform->createElement('submit', 'next', get_string('next')); + } + $buttonarray[] = &$mform->createElement('cancel'); + $mform->addGroup($buttonarray, 'extension_buttonar', '', array(' '), false); + $mform->closeHeaderBefore('extension_buttonar'); + $mform->setType('extension_buttonar', PARAM_RAW); + } +} /// OTHER STANDARD FUNCTIONS //////////////////////////////////////////////////////// @@ -3746,6 +4683,19 @@ return ' ('.$timetext.')'; } } +function assignment_display_extension($extension = null, $timemodified = 0, $timedue) { + $userextension = ''; + if (!empty($extension) && !empty($extension->extension)) { + $userextension = get_string('extension', 'assignment') .':'. format_time($extension->extension - $timedue); + $earlysubmission = ''; + if (!empty($timemodified)) { + $submissiontime = format_time($extension->extension - $timemodified); + $earlysubmission = get_string('early', 'assignment',$submissiontime); + } + return ' ('.$userextension .', '.$earlysubmission.')'; + } + return ''; +} function assignment_get_view_actions() { return array('view'); diff -Naur moodle2.2_ori//mod/assignment/styles.css moodle2.2//mod/assignment/styles.css --- moodle2.2_ori//mod/assignment/styles.css 2011-12-06 14:52:45.000000000 +0530 +++ moodle2.2//mod/assignment/styles.css 2012-04-06 21:01:06.000000000 +0530 @@ -11,6 +11,7 @@ .path-mod-assignment .files img {margin-right: 4px;} .path-mod-assignment .files a {white-space:nowrap;} .path-mod-assignment .late {color: red;} +.path-mod-assignment .sfextension {color: #FF1975;} /** Styles for submissions.php **/ #page-mod-assignment-submissions fieldset.felement {margin-left: 16%;} @@ -25,6 +26,24 @@ #page-mod-assignment-submissions .submissions .finalgrade {text-align: right;} #page-mod-assignment-submissions .submissions .header.noheader {display:none;} #page-mod-assignment-submissions .qgprefs #optiontable {text-align:right;margin-left:auto;} +/** styles for extensions.php **/ +#page-mod-assignment-extensions fieldset.felement {margin-left: 16%;} +#page-mod-assignment-extensions .header .commands {display: inline;} +#page-mod-assignment-extensions .picture {width: 35px;} +#page-mod-assignment-extensions .fullname, +#page-mod-assignment-extensions .extensioncomment, +#page-mod-assignment-extensions .extension {text-align: left;} +#page-mod-assignment-extensions .status, +#page-mod-assignment-extensions th.extension, +#page-mod-assignment-extensions th.extensioncomment {text-align: center;} +#page-mod-assignment-extensions .finalextension {text-align: center;} +#page-mod-assignment-extensions .extensions .header.noheader {display:none;} +#page-mod-assignment-extensions #dates {width: 50%; margin-left: 25%;} +#page-mod-assignment-extensions #dates .c0 {font-weight:bold; width:50%; text-align:right;} +#page-mod-assignment-extensions #fdates .fitemtitle {font-weight:bold; } +#page-mod-assignment-extensions #noexrequired {font-weight:bold; text-align:center; color:red;} + + /** Styles for view.php **/ #page-mod-assignment-view .feedback {margin:10px auto;} @@ -35,13 +54,19 @@ #page-mod-assignment-submissions .mform.optionspref .fitem .fitemtitle {width:50%;} #page-mod-assignment-submissions .mform.optionspref .fitem .felement {width: 30%; margin-left: 51%;} +#page-mod-assignment-extensions .mform.optionspref .fitem .fitemtitle {width:50%; text-align:right;} +#page-mod-assignment-extensions .mform.optionspref .fitem .felement {width: 30%;margin-left: 51%;} + #page-mod-assignment-submissions .optionspref {width: 50%;} #page-mod-assignment-submissions .fastgbutton {text-align: center;} +#page-mod-assignment-extensions .optionspref {width: 50%; margin-left:20%;} +#page-mod-assignment-extensions .fastebutton {text-align: center;} + #page-mod-assignment-submissions.dir-rtl .fullname, #page-mod-assignment-submissions.dir-rtl .timemodified, #page-mod-assignment-submissions.dir-rtl .timemarked {text-align:right;} #page-mod-assignment-submissions.dir-rtl .mform.optionspref .fitem .fitemtitle {text-align:left;} #page-mod-assignment-type-uploadsingle-upload.dir-rtl .mdl-left {text-align:right;} -.mod-assignment-download-link {text-align:right;} \ No newline at end of file +.mod-assignment-download-link {text-align:right;} diff -Naur moodle2.2_ori//mod/assignment/type/online/assignment.class.php moodle2.2//mod/assignment/type/online/assignment.class.php --- moodle2.2_ori//mod/assignment/type/online/assignment.class.php 2011-12-06 14:52:45.000000000 +0530 +++ moodle2.2//mod/assignment/type/online/assignment.class.php 2012-04-06 21:08:52.000000000 +0530 @@ -152,7 +152,11 @@ if (!$this->assignment->timeavailable && !$this->assignment->timedue) { return; } - + $extension=$this->get_extension(); + if ($extension) { + $extensiontime=$extension->extension; + $comment=$extension->extensioncomment; + } echo $OUTPUT->box_start('generalbox boxaligncenter', 'dates'); echo '
'; if ($this->assignment->timeavailable) { @@ -161,6 +165,11 @@ } if ($this->assignment->timedue) { echo ''; + if ($extension_time) { + echo ''; + } else { + echo ' '; + } echo ' '; } $submission = $this->get_submission($USER->id); @@ -176,6 +185,11 @@ } echo '
'.get_string('duedate','assignment').':'.userdate($extension->extension).'
'.userdate($this->assignment->timedue).'
'.userdate($this->assignment->timedue).'
'; echo $OUTPUT->box_end(); + echo ''; + if ($extension && !empty($extension->extension) && !empty($extension->extensioncomment)) { + $comment=$OUTPUT->notification($comment, 'warning'); + echo $comment; + } } function update_submission($data) { diff -Naur moodle2.2_ori//mod/assignment/version.php moodle2.2//mod/assignment/version.php --- moodle2.2_ori//mod/assignment/version.php 2011-12-06 14:52:45.000000000 +0530 +++ moodle2.2//mod/assignment/version.php 2012-04-03 21:12:39.000000000 +0530 @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); -$module->version = 2011112900; // The current module version (Date: YYYYMMDDXX) +$module->version = 2012040402; // The current module version (Date: YYYYMMDDXX) $module->requires = 2011112900; // Requires this Moodle version $module->component = 'mod_assignment'; // Full name of the plugin (used for diagnostics) $module->cron = 60; diff -Naur moodle2.2_ori//theme/standard/style/modules.css moodle2.2//theme/standard/style/modules.css --- moodle2.2_ori//theme/standard/style/modules.css 2011-04-21 05:31:51.000000000 +0530 +++ moodle2.2//theme/standard/style/modules.css 2012-04-06 11:09:34.000000000 +0530 @@ -32,6 +32,8 @@ #page-mod-assignment-submissions .timemarked {font-size: 0.9em;} #page-mod-assignment-submissions .fgcontrols {margin-top: 1em;text-align:center;} #page-mod-assignment-submissions .fgcontrols .fastgbutton{margin-top: 0.5em;} +#page-mod-assignment-extensions table.extensions td.cell, +#page-mod-assignment-extensions table.extensions th{border:1px solid #DDD;vertical-align: middle; padding-left:5px; padding-right:5px;} #page-mod-assignment-view #dates {font-size: 0.8em;margin:30px auto;} #page-mod-assignment-view #dates .c0 {text-align:right;font-weight:bold;} #page-mod-assignment-view .feedback {border:1px solid #DDD;} @@ -191,4 +193,4 @@ #page-mod-survey-report .reportsummary, #page-mod-survey-report .studentreport, #page-mod-survey-report .reportbuttons, -#page-mod-survey-report .centerpara {text-align:center;} \ No newline at end of file +#page-mod-survey-report .centerpara {text-align:center;}