Merge branch 'w02_MDL-43529_m27_globals' of https://github.com/skodak/moodle
authorDan Poltawski <dan@moodle.com>
Tue, 14 Jan 2014 06:46:55 +0000 (14:46 +0800)
committerDan Poltawski <dan@moodle.com>
Tue, 14 Jan 2014 06:46:55 +0000 (14:46 +0800)
154 files changed:
backup/moodle2/restore_course_task.class.php
backup/moodle2/restore_stepslib.php
blocks/activity_modules/tests/behat/block_activity_modules.feature
blocks/private_files/styles.css [new file with mode: 0644]
calendar/lib.php
course/tests/externallib_test.php
course/yui/build/moodle-course-modchooser/moodle-course-modchooser-debug.js
course/yui/build/moodle-course-modchooser/moodle-course-modchooser-min.js
course/yui/build/moodle-course-modchooser/moodle-course-modchooser.js
course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes-debug.js
course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes-min.js
course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes.js
course/yui/src/modchooser/js/modchooser.js
course/yui/src/toolboxes/js/toolbox.js
grade/grading/form/guide/styles.css
lang/en/block.php
lang/en/moodle.php
lang/en/question.php
lib/dml/moodle_database.php
lib/dml/mssql_native_moodle_database.php
lib/dml/mysqli_native_moodle_database.php
lib/dml/oci_native_moodle_database.php
lib/dml/pgsql_native_moodle_database.php
lib/dml/sqlsrv_native_moodle_database.php
lib/dml/tests/dml_test.php
lib/form/yui/build/moodle-form-passwordunmask/moodle-form-passwordunmask-debug.js [new file with mode: 0644]
lib/form/yui/build/moodle-form-passwordunmask/moodle-form-passwordunmask-min.js [new file with mode: 0644]
lib/form/yui/build/moodle-form-passwordunmask/moodle-form-passwordunmask.js [new file with mode: 0644]
lib/form/yui/passwordunmask/passwordunmask.js [deleted file]
lib/form/yui/src/passwordunmask/build.json [new file with mode: 0644]
lib/form/yui/src/passwordunmask/js/passwordunmask.js [new file with mode: 0644]
lib/form/yui/src/passwordunmask/meta/passwordunmask.json [new file with mode: 0644]
lib/grade/tests/fixtures/lib.php
lib/outputrenderers.php
lib/upgrade.txt
lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-debug.js
lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-min.js
lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue.js
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-debug.js
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-min.js
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue.js
lib/yui/src/chooserdialogue/js/chooserdialogue.js
lib/yui/src/notification/js/dialogue.js
login/signup_form.php
mod/assign/backup/moodle2/backup_assign_stepslib.php
mod/assign/db/install.xml
mod/assign/db/upgrade.php
mod/assign/externallib.php
mod/assign/lang/en/assign.php
mod/assign/locallib.php
mod/assign/mod_form.php
mod/assign/quickgradingform.php
mod/assign/settings.php
mod/assign/tests/generator/lib.php
mod/assign/tests/locallib_test.php
mod/assign/tests/upgradelib_test.php
mod/assign/upgrade.txt
mod/assign/upgradelib.php
mod/assign/version.php
mod/assignment/assignment.js [deleted file]
mod/assignment/backup/moodle2/restore_assignment_activity_task.class.php
mod/assignment/backup/moodle2/restore_assignment_stepslib.php
mod/assignment/classes/plugininfo/assignment.php
mod/assignment/db/install.xml
mod/assignment/db/upgrade.php
mod/assignment/db/upgradelib.php [new file with mode: 0644]
mod/assignment/delete.php [deleted file]
mod/assignment/grade.php [deleted file]
mod/assignment/lang/en/assignment.php
mod/assignment/lib.php
mod/assignment/locallib.php [deleted file]
mod/assignment/mod_form.php
mod/assignment/renderer.php [deleted file]
mod/assignment/settings.php [deleted file]
mod/assignment/styles.css [deleted file]
mod/assignment/submissions.php [deleted file]
mod/assignment/tests/generator_test.php [deleted file]
mod/assignment/type/offline/assignment.class.php [deleted file]
mod/assignment/type/online/all.php [deleted file]
mod/assignment/type/online/assignment.class.php [deleted file]
mod/assignment/type/online/classes/event/assessable_uploaded.php [deleted file]
mod/assignment/type/online/file.php [deleted file]
mod/assignment/type/upgrade.txt
mod/assignment/type/upload/assignment.class.php [deleted file]
mod/assignment/type/upload/classes/event/assessable_submitted.php [deleted file]
mod/assignment/type/upload/classes/event/assessable_uploaded.php [deleted file]
mod/assignment/type/upload/notes.php [deleted file]
mod/assignment/type/upload/upload.php [deleted file]
mod/assignment/type/upload/upload_form.php [deleted file]
mod/assignment/type/uploadsingle/assignment.class.php [deleted file]
mod/assignment/type/uploadsingle/upload.php [deleted file]
mod/assignment/type/uploadsingle/upload_form.php [deleted file]
mod/assignment/upload.php [deleted file]
mod/assignment/version.php
mod/assignment/view.php
mod/lesson/locallib.php
mod/lti/classes/event/course_module_instance_list_viewed.php [new file with mode: 0644]
mod/lti/classes/event/course_module_viewed.php [new file with mode: 0644]
mod/lti/index.php
mod/lti/launch.php
mod/lti/view.php
mod/quiz/editlib.php
mod/quiz/startattempt.php
mod/quiz/summary.php
mod/scorm/classes/event/attempt_deleted.php [new file with mode: 0644]
mod/scorm/classes/event/course_module_instance_list_viewed.php [new file with mode: 0644]
mod/scorm/classes/event/course_module_viewed.php [new file with mode: 0644]
mod/scorm/classes/event/interactions_viewed.php [new file with mode: 0644]
mod/scorm/classes/event/report_viewed.php [new file with mode: 0644]
mod/scorm/classes/event/sco_launched.php [new file with mode: 0644]
mod/scorm/classes/event/tracks_viewed.php [new file with mode: 0644]
mod/scorm/classes/event/user_report_viewed.php [new file with mode: 0644]
mod/scorm/index.php
mod/scorm/lang/en/scorm.php
mod/scorm/loadSCO.php
mod/scorm/locallib.php
mod/scorm/player.php
mod/scorm/report.php
mod/scorm/report/basic/report.php
mod/scorm/report/interactions/report.php
mod/scorm/report/objectives/report.php
mod/scorm/report/userreport.php
mod/scorm/report/userreportinteractions.php
mod/scorm/report/userreporttracks.php
mod/scorm/request.js
mod/scorm/tests/event_test.php [new file with mode: 0644]
mod/scorm/view.php
mod/wiki/edit_form.php
mod/wiki/pagelib.php
question/classes/bank/search/category_condition.php [new file with mode: 0755]
question/classes/bank/search/condition.php [new file with mode: 0755]
question/classes/bank/search/hidden_condition.php [new file with mode: 0755]
question/editlib.php
question/engine/bank.php
question/upgrade.txt
question/yui/build/moodle-question-searchform/moodle-question-searchform-debug.js [new file with mode: 0644]
question/yui/build/moodle-question-searchform/moodle-question-searchform-min.js [new file with mode: 0644]
question/yui/build/moodle-question-searchform/moodle-question-searchform.js [new file with mode: 0644]
question/yui/src/searchform/build.json [new file with mode: 0644]
question/yui/src/searchform/js/searchform.js [new file with mode: 0644]
question/yui/src/searchform/meta/searchform.json [new file with mode: 0644]
theme/base/style/blocks.css
theme/bootstrapbase/less/moodle.less
theme/bootstrapbase/less/moodle/blocks.less
theme/bootstrapbase/less/moodle/core.less
theme/bootstrapbase/less/moodle/grade.less [new file with mode: 0644]
theme/bootstrapbase/less/moodle/user.less
theme/bootstrapbase/renderers/core_renderer.php
theme/bootstrapbase/style/moodle.css
theme/boxxie/style/core.css
theme/canvas/style/mods.css
theme/formfactor/style/mods.css
theme/fusion/style/core.css
theme/standard/style/modules.css

index e9058b8..d32e1e2 100644 (file)
@@ -124,6 +124,7 @@ class restore_course_task extends restore_task {
         $contents = array();
 
         $contents[] = new restore_decode_content('course', 'summary');
+        $contents[] = new restore_decode_content('event', 'description');
 
         return $contents;
     }
index a4e42ef..930a26a 100644 (file)
@@ -2223,6 +2223,7 @@ class restore_calendarevents_structure_step extends restore_structure_step {
         $result = $DB->record_exists_sql($sql, $arg);
         if (empty($result)) {
             $newitemid = $DB->insert_record('event', $params);
+            $this->set_mapping('event', $oldid, $newitemid);
             $this->set_mapping('event_description', $oldid, $newitemid, $restorefiles);
         }
 
index ba76908..f0ed3f5 100644 (file)
@@ -11,13 +11,11 @@ Feature: Block activity modules
     And I expand "Activity modules" node
     And I follow "Manage activities"
     And I click on "//a[@title=\"Show\"]" "xpath_element" in the "Feedback" "table_row"
-    And I click on "//a[@title=\"Show\"]" "xpath_element" in the "Assignment (2.2)" "table_row"
 
   Scenario: Add activities block on the frontpage
     And the following "activities" exists:
       | activity   | name                        | intro                              | course               | idnumber    |
       | assign     | Frontpage assignment name   | Frontpage assignment description   | Acceptance test site | assign0     |
-      | assignment | Frontpage assignment22 name | Frontpage assignment22 description | Acceptance test site | assignment0 |
       | book       | Frontpage book name         | Frontpage book description         | Acceptance test site | book0       |
       | chat       | Frontpage chat name         | Frontpage chat description         | Acceptance test site | chat0       |
       | choice     | Frontpage choice name       | Frontpage choice description       | Acceptance test site | choice0     |
@@ -45,9 +43,6 @@ Feature: Block activity modules
     And I click on "Assignments" "link" in the "Activities" "block"
     Then I should see "Frontpage assignment name"
     And I am on homepage
-    And I click on "Assignments (2.2)" "link" in the "Activities" "block"
-    And I should see "Frontpage assignment22 name"
-    And I am on homepage
     And I click on "Chats" "link" in the "Activities" "block"
     And I should see "Frontpage chat name"
     And I am on homepage
@@ -99,7 +94,6 @@ Feature: Block activity modules
     And the following "activities" exists:
       | activity   | name                   | intro                         | course | idnumber    |
       | assign     | Test assignment name   | Test assignment description   | C1     | assign1     |
-      | assignment | Test assignment22 name | Test assignment22 description | C1     | assignment1 |
       | book       | Test book name         | Test book description         | C1     | book1       |
       | chat       | Test chat name         | Test chat description         | C1     | chat1       |
       | choice     | Test choice name       | Test choice description       | C1     | choice1     |
@@ -128,9 +122,6 @@ Feature: Block activity modules
     And I click on "Assignments" "link" in the "Activities" "block"
     Then I should see "Test assignment name"
     And I follow "Course 1"
-    And I click on "Assignments (2.2)" "link" in the "Activities" "block"
-    And I should see "Test assignment22 name"
-    And I follow "Course 1"
     And I click on "Chats" "link" in the "Activities" "block"
     And I should see "Test chat name"
     And I follow "Course 1"
diff --git a/blocks/private_files/styles.css b/blocks/private_files/styles.css
new file mode 100644 (file)
index 0000000..95fd6bb
--- /dev/null
@@ -0,0 +1,5 @@
+/* Rule so that the table tree view works with word-wrap: break-word. */
+.block_private_files .content table {
+    table-layout: fixed;
+    width: 100%;
+}
\ No newline at end of file
index be9f906..69de81d 100644 (file)
@@ -575,32 +575,6 @@ function calendar_get_upcoming($courses, $groups, $users, $daysinfuture, $maxeve
                         continue;
                     }
                 }
-                if ($event->modulename == 'assignment'){
-                    // create calendar_event to test edit_event capability
-                    // this new event will also prevent double creation of calendar_event object
-                    $checkevent = new calendar_event($event);
-                    // TODO: rewrite this hack somehow
-                    if (!calendar_edit_event_allowed($checkevent)){ // cannot manage entries, eg. student
-                        if (!$assignment = $DB->get_record('assignment', array('id'=>$event->instance))) {
-                            // print_error("invalidid", 'assignment');
-                            continue;
-                        }
-                        // assign assignment to assignment object to use hidden_is_hidden method
-                        require_once($CFG->dirroot.'/mod/assignment/lib.php');
-
-                        if (!file_exists($CFG->dirroot.'/mod/assignment/type/'.$assignment->assignmenttype.'/assignment.class.php')) {
-                            continue;
-                        }
-                        require_once ($CFG->dirroot.'/mod/assignment/type/'.$assignment->assignmenttype.'/assignment.class.php');
-
-                        $assignmentclass = 'assignment_'.$assignment->assignmenttype;
-                        $assignmentinstance = new $assignmentclass($cm->id, $assignment, $cm);
-
-                        if ($assignmentinstance->description_is_hidden()){//force not to show description before availability
-                            $event->description = get_string('notavailableyet', 'assignment');
-                        }
-                    }
-                }
             }
 
             if ($processed >= $display->maxevents) {
index 994161a..a83ca83 100644 (file)
@@ -900,13 +900,13 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
         $record = new stdClass();
         $record->course = $course->id;
         $module1 = self::getDataGenerator()->create_module('forum', $record);
-        $module2 = self::getDataGenerator()->create_module('assignment', $record);
+        $module2 = self::getDataGenerator()->create_module('assign', $record);
 
         // Check the forum was correctly created.
         $this->assertEquals(1, $DB->count_records('forum', array('id' => $module1->id)));
 
         // Check the assignment was correctly created.
-        $this->assertEquals(1, $DB->count_records('assignment', array('id' => $module2->id)));
+        $this->assertEquals(1, $DB->count_records('assign', array('id' => $module2->id)));
 
         // Check data exists in the course modules table.
         $this->assertEquals(2, $DB->count_records_select('course_modules', 'id = :module1 OR id = :module2',
@@ -939,7 +939,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
         $this->assertEquals(0, $DB->count_records('forum', array('id' => $module1->id)));
 
         // Check the assignment was deleted.
-        $this->assertEquals(0, $DB->count_records('assignment', array('id' => $module2->id)));
+        $this->assertEquals(0, $DB->count_records('assign', array('id' => $module2->id)));
 
         // Check we retrieve no data in the course modules table.
         $this->assertEquals(0, $DB->count_records_select('course_modules', 'id = :module1 OR id = :module2',
@@ -955,7 +955,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
 
         // Create two modules.
         $module1 = self::getDataGenerator()->create_module('forum', $record);
-        $module2 = self::getDataGenerator()->create_module('assignment', $record);
+        $module2 = self::getDataGenerator()->create_module('assign', $record);
 
         // Since these modules were recreated the user will not have capabilities
         // to delete them, ensure exception is thrown if they try.
index d3bf0c1..183420c 100644 (file)
Binary files a/course/yui/build/moodle-course-modchooser/moodle-course-modchooser-debug.js and b/course/yui/build/moodle-course-modchooser/moodle-course-modchooser-debug.js differ
index f9bddf4..0425628 100644 (file)
Binary files a/course/yui/build/moodle-course-modchooser/moodle-course-modchooser-min.js and b/course/yui/build/moodle-course-modchooser/moodle-course-modchooser-min.js differ
index d3bf0c1..183420c 100644 (file)
Binary files a/course/yui/build/moodle-course-modchooser/moodle-course-modchooser.js and b/course/yui/build/moodle-course-modchooser/moodle-course-modchooser.js differ
index 3268417..7eb72a7 100644 (file)
Binary files a/course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes-debug.js and b/course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes-debug.js differ
index 67d01c9..7a2e8e5 100644 (file)
Binary files a/course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes-min.js and b/course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes-min.js differ
index 3268417..7eb72a7 100644 (file)
Binary files a/course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes.js and b/course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes.js differ
index b1033e3..f9627d2 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 var CSS = {
-    PAGECONTENT : 'div#page-content',
+    PAGECONTENT : 'body',
     SECTION : 'li.section',
     SECTIONMODCHOOSER : 'span.section-modchooser-link',
     SITEMENU : 'div.block_site_main_menu',
index 7fdfaac..7fd7b3b 100644 (file)
@@ -47,7 +47,7 @@ var CSS = {
         INSTANCENAME : 'span.instancename',
         MODINDENTDIV : '.mod-indent',
         MODINDENTOUTER : '.mod-indent-outer',
-        PAGECONTENT : 'div#page-content',
+        PAGECONTENT : 'body',
         SECTIONLI : 'li.section',
         SHOW : 'a.'+CSS.SHOW,
         SHOWHIDE : 'a.editing_showhide'
index 8ea947c..715d56e 100644 (file)
@@ -11,8 +11,8 @@
 .gradingform_guide .criterion .remark {vertical-align: top;}
 
 .gradingform_guide.editor .criterion .controls,
-.gradingform_guide .criterion .description,
-.gradingform_guide .criterion .remark {padding:3px;}
+.gradingform_guide.editor .criterion .description,
+.gradingform_guide.editor .criterion .remark {padding:3px;}
 
 .gradingform_guide .criteria {height:100%;}
 .gradingform_guide .criterion {border:1px solid #DDD;overflow: hidden;}
 .gradingform_guide.editor .hiddenelement {display:none;}
 .gradingform_guide.editor .pseudotablink {background-color:transparent;border:0 solid;height:1px;width:1px;color:transparent;padding:0;margin:0;position:relative;float:right;}
 
-.gradingform_guide .markingguidecomment {cursor: pointer;}
-.jsenabled .gradingform_guide .markingguidecomment:before {content: url([[pix:t/add]]);padding-right:2px;}
+.jsenabled .gradingform_guide .markingguidecomment {cursor: pointer;}
+.jsenabled .gradingform_guide .markingguidecomment:before {
+    content: url([[pix:t/add]]);
+    padding-right:2px;
+}
+.dir-rtl.jsenabled .gradingform_guide .markingguidecomment:before {
+    padding-right: 0;
+    padding-left: 2px;
+}
 .gradingform_guide .commentheader  {font-weight:bold;font-size:1.1em;padding-bottom:5px;}
 
 .jsenabled .gradingform_guide .criterionnamelabel {display: none;}
 .jsenabled .gradingform_guide .criterionshortname {font-weight:bold;}
 .gradingform_guide table {width: 100%}
+.gradingform_guide .descriptionreadonly {
+    vertical-align: top;
+}
 .gradingform_guide .criteriondescriptionmarkers {width: 300px;}
-.gradingform_guide .markingguideremark {width: 100%;}
-.gradingform_guide .criteriondescriptionscore {display: inline;}
\ No newline at end of file
+.gradingform_guide .markingguideremark {
+    margin: 0;
+    width: 100%;
+    -moz-box-sizing: border-box;
+         box-sizing: border-box;
+}
+.gradingform_guide .criteriondescriptionscore {display: inline;}
+.gradingform_guide .score label {
+    display: block;
+}
+.gradingform_guide .score input {
+    margin: 0;
+    width: auto;
+}
index 00527cd..e38b5a4 100644 (file)
@@ -50,6 +50,7 @@ $string['hidepanel'] = 'Hide panel';
 $string['moveblock'] = 'Move {$a} block';
 $string['moveblockafter'] = 'Move block to after {$a} block';
 $string['moveblockbefore'] = 'Move block to before {$a} block';
+$string['moveblockinregion'] = 'Move block to {$a} region';
 $string['movingthisblockcancel'] = 'Moving this block ({$a})';
 $string['onthispage'] = 'On this page';
 $string['pagetypes'] = 'Page types';
index da2502e..9c08415 100644 (file)
@@ -1121,8 +1121,6 @@ $string['minute'] = 'minute';
 $string['minutes'] = 'minutes';
 $string['miscellaneous'] = 'Miscellaneous';
 $string['missingcategory'] = 'You need to choose a category';
-$string['missingcity'] = 'Missing city/town';
-$string['missingcountry'] = 'Missing country';
 $string['missingdescription'] = 'Missing description';
 $string['missingemail'] = 'Missing email address';
 $string['missingfirstname'] = 'Missing given name';
index 092e50f..d2923b1 100644 (file)
@@ -25,6 +25,7 @@
 $string['addmorechoiceblanks'] = 'Blanks for {no} more choices';
 $string['addcategory'] = 'Add category';
 $string['adminreport'] = 'Report on possible problems in your question database.';
+$string['advancedsearchoptions'] = 'Search options';
 $string['answers'] = 'Answers';
 $string['availableq'] = 'Available?';
 $string['badbase'] = 'Bad base before **: {$a}**';
index 4828dcf..070f0cb 100644 (file)
@@ -924,6 +924,54 @@ abstract class moodle_database {
         }
     }
 
+    /**
+     * Ensures that limit params are numeric and positive integers, to be passed to the database.
+     * We explicitly treat null, '' and -1 as 0 in order to provide compatibility with how limit
+     * values have been passed historically.
+     *
+     * @param int $limitfrom Where to start results from
+     * @param int $limitnum How many results to return
+     * @return array Normalised limit params in array($limitfrom, $limitnum)
+     */
+    protected function normalise_limit_from_num($limitfrom, $limitnum) {
+        global $CFG;
+
+        // We explicilty treat these cases as 0.
+        if ($limitfrom === null || $limitfrom === '' || $limitfrom === -1) {
+            $limitfrom = 0;
+        }
+        if ($limitnum === null || $limitnum === '' || $limitnum === -1) {
+            $limitnum = 0;
+        }
+
+        if ($CFG->debugdeveloper) {
+            if (!is_numeric($limitfrom)) {
+                $strvalue = var_export($limitfrom, true);
+                debugging("Non-numeric limitfrom parameter detected: $strvalue, did you pass the correct arguments?",
+                    DEBUG_DEVELOPER);
+            } else if ($limitfrom < 0) {
+                debugging("Negative limitfrom parameter detected: $limitfrom, did you pass the correct arguments?",
+                    DEBUG_DEVELOPER);
+            }
+
+            if (!is_numeric($limitnum)) {
+                $strvalue = var_export($limitnum, true);
+                debugging("Non-numeric limitnum parameter detected: $strvalue, did you pass the correct arguments?",
+                    DEBUG_DEVELOPER);
+            } else if ($limitnum < 0) {
+                debugging("Negative limitnum parameter detected: $limitnum, did you pass the correct arguments?",
+                    DEBUG_DEVELOPER);
+            }
+        }
+
+        $limitfrom = (int)$limitfrom;
+        $limitnum  = (int)$limitnum;
+        $limitfrom = max(0, $limitfrom);
+        $limitnum  = max(0, $limitnum);
+
+        return array($limitfrom, $limitnum);
+    }
+
     /**
      * Return tables in database WITHOUT current prefix.
      * @param bool $usecache if true, returns list of cached tables.
index 70bd6f3..0a324b1 100644 (file)
@@ -693,10 +693,9 @@ class mssql_native_moodle_database extends moodle_database {
      * @throws dml_exception A DML specific exception is thrown for any errors.
      */
     public function get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) {
-        $limitfrom = (int)$limitfrom;
-        $limitnum  = (int)$limitnum;
-        $limitfrom = ($limitfrom < 0) ? 0 : $limitfrom;
-        $limitnum  = ($limitnum < 0)  ? 0 : $limitnum;
+
+        list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
+
         if ($limitfrom or $limitnum) {
             if ($limitnum >= 1) { // Only apply TOP clause if we have any limitnum (limitfrom offset is handled later)
                 $fetch = $limitfrom + $limitnum;
index 34320d9..3cb62a3 100644 (file)
@@ -912,10 +912,8 @@ class mysqli_native_moodle_database extends moodle_database {
      * @throws dml_exception A DML specific exception is thrown for any errors.
      */
     public function get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) {
-        $limitfrom = (int)$limitfrom;
-        $limitnum  = (int)$limitnum;
-        $limitfrom = ($limitfrom < 0) ? 0 : $limitfrom;
-        $limitnum  = ($limitnum < 0)  ? 0 : $limitnum;
+
+        list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
 
         if ($limitfrom or $limitnum) {
             if ($limitnum < 1) {
@@ -976,10 +974,8 @@ class mysqli_native_moodle_database extends moodle_database {
      * @throws dml_exception A DML specific exception is thrown for any errors.
      */
     public function get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) {
-        $limitfrom = (int)$limitfrom;
-        $limitnum  = (int)$limitnum;
-        $limitfrom = ($limitfrom < 0) ? 0 : $limitfrom;
-        $limitnum  = ($limitnum < 0)  ? 0 : $limitnum;
+
+        list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
 
         if ($limitfrom or $limitnum) {
             if ($limitnum < 1) {
index 0c6f700..00f79d6 100644 (file)
@@ -712,11 +712,7 @@ class oci_native_moodle_database extends moodle_database {
      */
     private function get_limit_sql($sql, array $params = null, $limitfrom=0, $limitnum=0) {
 
-        $limitfrom = (int)$limitfrom;
-        $limitnum  = (int)$limitnum;
-        $limitfrom = ($limitfrom < 0) ? 0 : $limitfrom;
-        $limitnum  = ($limitnum < 0)  ? 0 : $limitnum;
-
+        list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
         // TODO: Add the /*+ FIRST_ROWS */ hint if there isn't another hint
 
         if ($limitfrom and $limitnum) {
index 5c369a7..2ee1635 100644 (file)
@@ -681,10 +681,9 @@ class pgsql_native_moodle_database extends moodle_database {
      * @throws dml_exception A DML specific exception is thrown for any errors.
      */
     public function get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) {
-        $limitfrom = (int)$limitfrom;
-        $limitnum  = (int)$limitnum;
-        $limitfrom = ($limitfrom < 0) ? 0 : $limitfrom;
-        $limitnum  = ($limitnum < 0)  ? 0 : $limitnum;
+
+        list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
+
         if ($limitfrom or $limitnum) {
             if ($limitnum < 1) {
                 $limitnum = "ALL";
@@ -724,10 +723,9 @@ class pgsql_native_moodle_database extends moodle_database {
      * @throws dml_exception A DML specific exception is thrown for any errors.
      */
     public function get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) {
-        $limitfrom = (int)$limitfrom;
-        $limitnum  = (int)$limitnum;
-        $limitfrom = ($limitfrom < 0) ? 0 : $limitfrom;
-        $limitnum  = ($limitnum < 0)  ? 0 : $limitnum;
+
+        list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
+
         if ($limitfrom or $limitnum) {
             if ($limitnum < 1) {
                 $limitnum = "ALL";
index 6f12524..f6cab36 100644 (file)
@@ -762,10 +762,8 @@ class sqlsrv_native_moodle_database extends moodle_database {
      * @throws dml_exception A DML specific exception is thrown for any errors.
      */
     public function get_recordset_sql($sql, array $params = null, $limitfrom = 0, $limitnum = 0) {
-        $limitfrom = (int)$limitfrom;
-        $limitnum = (int)$limitnum;
-        $limitfrom = max(0, $limitfrom);
-        $limitnum = max(0, $limitnum);
+
+        list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
 
         if ($limitfrom or $limitnum) {
             if ($limitnum >= 1) { // Only apply TOP clause if we have any limitnum (limitfrom offset is handled later)
index ceed3db..869d6ba 100644 (file)
@@ -4997,6 +4997,74 @@ class core_dml_testcase extends database_driver_testcase {
         $this->assertEquals(2, reset($records)->count);
         $this->assertEquals(2, end($records)->count);
     }
+
+    /**
+     * Test debugging messages about invalid limit number values.
+     */
+    public function test_invalid_limits_debugging() {
+        $DB = $this->tdb;
+        $dbman = $DB->get_manager();
+
+        // Setup test data.
+        $table = $this->get_test_table();
+        $tablename = $table->getName();
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $dbman->create_table($table);
+        $DB->insert_record($tablename, array('course' => '1'));
+
+        // Verify that get_records_sql throws debug notices with invalid limit params.
+        $DB->get_records_sql("SELECT * FROM {{$tablename}}", null, 'invalid');
+        $this->assertDebuggingCalled("Non-numeric limitfrom parameter detected: 'invalid', did you pass the correct arguments?");
+
+        $DB->get_records_sql("SELECT * FROM {{$tablename}}", null, 1, 'invalid');
+        $this->assertDebuggingCalled("Non-numeric limitnum parameter detected: 'invalid', did you pass the correct arguments?");
+
+        // Verify that get_recordset_sql throws debug notices with invalid limit params.
+        $rs = $DB->get_recordset_sql("SELECT * FROM {{$tablename}}", null, 'invalid');
+        $this->assertDebuggingCalled("Non-numeric limitfrom parameter detected: 'invalid', did you pass the correct arguments?");
+        $rs->close();
+
+        $rs = $DB->get_recordset_sql("SELECT * FROM {{$tablename}}", null, 1, 'invalid');
+        $this->assertDebuggingCalled("Non-numeric limitnum parameter detected: 'invalid', did you pass the correct arguments?");
+        $rs->close();
+
+        // Verify that some edge cases do no create debugging messages.
+        // String form of integer values.
+        $DB->get_records_sql("SELECT * FROM {{$tablename}}", null, '1');
+        $this->assertDebuggingNotCalled();
+        $DB->get_records_sql("SELECT * FROM {{$tablename}}", null, 1, '2');
+        $this->assertDebuggingNotCalled();
+        // Empty strings.
+        $DB->get_records_sql("SELECT * FROM {{$tablename}}", null, '');
+        $this->assertDebuggingNotCalled();
+        $DB->get_records_sql("SELECT * FROM {{$tablename}}", null, 1, '');
+        $this->assertDebuggingNotCalled();
+        // Null values.
+        $DB->get_records_sql("SELECT * FROM {{$tablename}}", null, null);
+        $this->assertDebuggingNotCalled();
+        $DB->get_records_sql("SELECT * FROM {{$tablename}}", null, 1, null);
+        $this->assertDebuggingNotCalled();
+
+        // Verify that empty arrays DO create debugging mesages.
+        $DB->get_records_sql("SELECT * FROM {{$tablename}}", null, array());
+        $this->assertDebuggingCalled("Non-numeric limitfrom parameter detected: array (\n), did you pass the correct arguments?");
+        $DB->get_records_sql("SELECT * FROM {{$tablename}}", null, 1, array());
+        $this->assertDebuggingCalled("Non-numeric limitnum parameter detected: array (\n), did you pass the correct arguments?");
+
+        // Verify Negative number handling:
+        // -1 is explicitly treated as 0 for historical reasons.
+        $DB->get_records_sql("SELECT * FROM {{$tablename}}", null, -1);
+        $this->assertDebuggingNotCalled();
+        $DB->get_records_sql("SELECT * FROM {{$tablename}}", null, 1, -1);
+        $this->assertDebuggingNotCalled();
+        // Any other negative values should throw debugging messages.
+        $DB->get_records_sql("SELECT * FROM {{$tablename}}", null, -2);
+        $this->assertDebuggingCalled("Negative limitfrom parameter detected: -2, did you pass the correct arguments?");
+        $DB->get_records_sql("SELECT * FROM {{$tablename}}", null, 1, -2);
+        $this->assertDebuggingCalled("Negative limitnum parameter detected: -2, did you pass the correct arguments?");
+    }
 }
 
 /**
diff --git a/lib/form/yui/build/moodle-form-passwordunmask/moodle-form-passwordunmask-debug.js b/lib/form/yui/build/moodle-form-passwordunmask/moodle-form-passwordunmask-debug.js
new file mode 100644 (file)
index 0000000..8ec50a7
Binary files /dev/null and b/lib/form/yui/build/moodle-form-passwordunmask/moodle-form-passwordunmask-debug.js differ
diff --git a/lib/form/yui/build/moodle-form-passwordunmask/moodle-form-passwordunmask-min.js b/lib/form/yui/build/moodle-form-passwordunmask/moodle-form-passwordunmask-min.js
new file mode 100644 (file)
index 0000000..6c426ff
Binary files /dev/null and b/lib/form/yui/build/moodle-form-passwordunmask/moodle-form-passwordunmask-min.js differ
diff --git a/lib/form/yui/build/moodle-form-passwordunmask/moodle-form-passwordunmask.js b/lib/form/yui/build/moodle-form-passwordunmask/moodle-form-passwordunmask.js
new file mode 100644 (file)
index 0000000..8ec50a7
Binary files /dev/null and b/lib/form/yui/build/moodle-form-passwordunmask/moodle-form-passwordunmask.js differ
diff --git a/lib/form/yui/passwordunmask/passwordunmask.js b/lib/form/yui/passwordunmask/passwordunmask.js
deleted file mode 100644 (file)
index 1bbefcc..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-YUI.add('moodle-form-passwordunmask', function(Y) {
-    var PASSWORDUNMASK = function() {
-        PASSWORDUNMASK.superclass.constructor.apply(this, arguments);
-    }
-
-    Y.extend(PASSWORDUNMASK, Y.Base, {
-        //Initialize checkbox if id is passed
-        initializer : function(params) {
-            if (params && params.formid) {
-               this.add_checkbox(params.formid, params.checkboxlabel, params.checkboxname);
-            }
-        },
-        //Create checkbox for unmasking password
-        add_checkbox : function(elementid, checkboxlabel, checkboxname) {
-            var node = Y.one('#'+elementid);
-
-            //retaining unmask div from previous implementation.
-            var unmaskdiv = Y.Node.create('<div id="'+elementid+'unmaskdiv" class="unmask"></div>');
-
-            //Add checkbox for unmasking to unmaskdiv
-            var unmaskchb = Y.Node.create('<input id="'+elementid+'unmask" type="checkbox" name="'+
-                checkboxname+'unmask">');
-            unmaskdiv.appendChild(unmaskchb);
-            //Attach event using static javascript function for unmasking password.
-            unmaskchb.on('click', function() {unmaskPassword(elementid);});
-
-            //Add label for checkbox to unmaskdiv
-            var unmasklabel = Y.Node.create('<label for="'+elementid+'unmask">'+checkboxlabel+'</label>');
-            unmaskdiv.appendChild(unmasklabel);
-
-            //Insert unmask div in the same div as password input.
-            node.get('parentNode').insert(unmaskdiv, node.get('lastNode'));
-        }
-    });
-
-    M.form = M.form || {};
-    M.form.passwordunmask = function(params) {
-        return new PASSWORDUNMASK(params);
-    }
-}, '@VERSION@', {requires:['base', 'node']});
diff --git a/lib/form/yui/src/passwordunmask/build.json b/lib/form/yui/src/passwordunmask/build.json
new file mode 100644 (file)
index 0000000..9ad9dac
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "name": "moodle-form-passwordunmask",
+    "builds": {
+        "moodle-form-passwordunmask": {
+            "jsfiles": [
+                "passwordunmask.js"
+            ]
+        }
+    }
+}
diff --git a/lib/form/yui/src/passwordunmask/js/passwordunmask.js b/lib/form/yui/src/passwordunmask/js/passwordunmask.js
new file mode 100644 (file)
index 0000000..63b4748
--- /dev/null
@@ -0,0 +1,39 @@
+var PASSWORDUNMASK = function() {
+    PASSWORDUNMASK.superclass.constructor.apply(this, arguments);
+};
+
+Y.extend(PASSWORDUNMASK, Y.Base, {
+    // Initialize checkbox if id is passed.
+    initializer : function(params) {
+        if (params && params.formid) {
+            this.add_checkbox(params.formid, params.checkboxlabel, params.checkboxname);
+        }
+    },
+
+    // Create checkbox for unmasking password.
+    add_checkbox : function(elementid, checkboxlabel, checkboxname) {
+        var node = Y.one('#'+elementid);
+
+        // Retaining unmask div from previous implementation.
+        var unmaskdiv = Y.Node.create('<div id="'+elementid+'unmaskdiv" class="unmask"></div>');
+
+        // Add checkbox for unmasking to unmaskdiv.
+        var unmaskchb = Y.Node.create('<input id="'+elementid+'unmask" type="checkbox" name="'+
+            checkboxname+'unmask">');
+        unmaskdiv.appendChild(unmaskchb);
+        // Attach event using static javascript function for unmasking password.
+        unmaskchb.on('click', function() {unmaskPassword(elementid);});
+
+        // Add label for checkbox to unmaskdiv.
+        var unmasklabel = Y.Node.create('<label for="'+elementid+'unmask">'+checkboxlabel+'</label>');
+        unmaskdiv.appendChild(unmasklabel);
+
+        // Insert unmask div in the same div as password input.
+        node.get('parentNode').insert(unmaskdiv, node.get('lastNode'));
+    }
+});
+
+M.form = M.form || {};
+M.form.passwordunmask = function(params) {
+    return new PASSWORDUNMASK(params);
+};
diff --git a/lib/form/yui/src/passwordunmask/meta/passwordunmask.json b/lib/form/yui/src/passwordunmask/meta/passwordunmask.json
new file mode 100644 (file)
index 0000000..1830917
--- /dev/null
@@ -0,0 +1,8 @@
+{
+    "moodle-form-passwordunmask": {
+        "requires": [
+            "node",
+            "base"
+        ]
+    }
+}
index cc3dbb0..52613b5 100644 (file)
@@ -81,11 +81,11 @@ abstract class grade_base_testcase extends advanced_testcase {
     }
 
     private function load_modules() {
-        $this->activities[0] = $this->getDataGenerator()->create_module('assignment', array('course'=>$this->course->id));
-        $this->course_module[0] = get_coursemodule_from_instance('assignment', $this->activities[0]->id);
+        $this->activities[0] = $this->getDataGenerator()->create_module('assign', array('course'=>$this->course->id));
+        $this->course_module[0] = get_coursemodule_from_instance('assign', $this->activities[0]->id);
 
-        $this->activities[1] = $this->getDataGenerator()->create_module('assignment', array('course'=>$this->course->id));
-        $this->course_module[1] = get_coursemodule_from_instance('assignment', $this->activities[1]->id);
+        $this->activities[1] = $this->getDataGenerator()->create_module('assign', array('course'=>$this->course->id));
+        $this->course_module[1] = get_coursemodule_from_instance('assign', $this->activities[1]->id);
 
         $this->activities[2] = $this->getDataGenerator()->create_module('forum', array('course'=>$this->course->id));
         $this->course_module[2] = get_coursemodule_from_instance('forum', $this->activities[2]->id);
index af3fea5..d43d7c7 100644 (file)
@@ -1413,7 +1413,7 @@ class core_renderer extends renderer_base {
                 $output .= $this->block($bc, $region);
                 $lastblock = $bc->title;
             } else if ($bc instanceof block_move_target) {
-                $output .= $this->block_move_target($bc, $zones, $lastblock);
+                $output .= $this->block_move_target($bc, $zones, $lastblock, $region);
             } else {
                 throw new coding_exception('Unexpected type of thing (' . get_class($bc) . ') found in list of block contents.');
             }
@@ -1427,11 +1427,18 @@ class core_renderer extends renderer_base {
      * @param block_move_target $target with the necessary details.
      * @param array $zones array of areas where the block can be moved to
      * @param string $previous the block located before the area currently being rendered.
+     * @param string $region the name of the region
      * @return string the HTML to be output.
      */
-    public function block_move_target($target, $zones, $previous) {
+    public function block_move_target($target, $zones, $previous, $region) {
         if ($previous == null) {
-            $position = get_string('moveblockbefore', 'block', $zones[0]);
+            if (empty($zones)) {
+                // There are no zones, probably because there are no blocks.
+                $regions = $this->page->theme->get_all_block_regions();
+                $position = get_string('moveblockinregion', 'block', $regions[$region]);
+            } else {
+                $position = get_string('moveblockbefore', 'block', $zones[0]);
+            }
         } else {
             $position = get_string('moveblockafter', 'block', $previous);
         }
index afc80e3..15a06ca 100644 (file)
@@ -3,6 +3,8 @@ information provided here is intended especially for developers.
 
 === 2.7 ===
 
+* $core_renderer->block_move_target() changed to support more verbose move-block-here descriptions.
+
 DEPRECATIONS:
 * Abstract class \core\event\course_module_instances_list_viewed is deprecated now, use \core\event\instances_list_viewed instead.
 * mod_book\event\instances_list_viewed has been deprecated. Please use mod_book\event\course_module_instance_list_viewed instead.
index 1e19920..a31d211 100644 (file)
Binary files a/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-debug.js and b/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-debug.js differ
index ed61bb1..fa8b2e3 100644 (file)
Binary files a/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-min.js and b/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-min.js differ
index 1e19920..a31d211 100644 (file)
Binary files a/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue.js and b/lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue.js differ
index b4b62ea..ff36c28 100644 (file)
Binary files a/lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-debug.js and b/lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-debug.js differ
index b289ee5..62cd2fe 100644 (file)
Binary files a/lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-min.js and b/lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-min.js differ
index 77dc52d..0c3269e 100644 (file)
Binary files a/lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue.js and b/lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue.js differ
index 2371c65..a2af79d 100644 (file)
@@ -44,7 +44,8 @@ Y.extend(CHOOSERDIALOGUE, Y.Base, {
             zindex : 100, // Display in front of other items
             modal: true, // This dialogue should be modal.
             shim : true,
-            closeButtonTitle : this.get('closeButtonTitle')
+            closeButtonTitle : this.get('closeButtonTitle'),
+            render : false
         };
 
         // Override with additional options
index ae4a4d4..edd85e8 100644 (file)
@@ -39,15 +39,8 @@ DIALOGUE = function(c) {
     }
 
     config.srcNode =    '#'+id;
-    config.width =      config.width || '400px';
-    config.center =     config.centered && true;
-    config.centered =   false;
     config.COUNT = COUNT;
 
-    if (config.width === 'auto') {
-        delete config.width;
-    }
-
     // closeButton param to keep the stable versions API.
     if (config.closeButton === false) {
         config.buttons = null;
@@ -84,7 +77,9 @@ Y.extend(DIALOGUE, Y.Panel, {
     initializer : function(config) {
         var bb;
 
-        this.render();
+        if (this.get('render')) {
+            this.render();
+        }
         this.makeResponsive();
         this.after('visibleChange', this.visibilityChanged, this);
         if (config.center) {
@@ -448,4 +443,77 @@ Y.extend(DIALOGUE, Y.Panel, {
     }
 });
 
+Y.Base.modifyAttrs(DIALOGUE, {
+    /**
+     * String with units, or number, representing the width of the Widget.
+     * If a number is provided, the default unit, defined by the Widgets
+     * DEF_UNIT, property is used.
+     *
+     * If a value of 'auto' is used, then an empty String is instead
+     * returned.
+     *
+     * @attribute width
+     * @default '400px'
+     * @type {String|Number}
+     */
+    width: {
+        value: '400px',
+        setter: function(value) {
+            if (value === 'auto') {
+                return '';
+            }
+            return value;
+        }
+    },
+
+    /**
+     * Boolean indicating whether or not the Widget is visible.
+     *
+     * We override this from the default Widget attribute value.
+     *
+     * @attribute visible
+     * @default false
+     * @type Boolean
+     */
+    visible: {
+        value: false
+    },
+
+    /**
+     * A convenience Attribute, which can be used as a shortcut for the
+     * `align` Attribute.
+     *
+     * Note: We override this in Moodle such that it sets a value for the
+     * `center` attribute if set. The `centered` will always return false.
+     *
+     * @attribute centered
+     * @type Boolean|Node
+     * @default false
+     */
+    centered: {
+        setter: function(value) {
+            if (value) {
+                this.set('center', true);
+            }
+            return false;
+        }
+    },
+
+    /**
+     * Boolean determining whether to render the widget during initialisation.
+     *
+     * We override this to change the default from false to true for the dialogue.
+     * We then proceed to early render the dialogue during our initialisation rather than waiting
+     * for YUI to render it after that.
+     *
+     * @attribute render
+     * @type Boolean
+     * @default true
+     */
+    render : {
+        value : true,
+        writeOnce : true
+    }
+});
+
 M.core.dialogue = DIALOGUE;
index 3422c8d..71ad670 100644 (file)
@@ -73,7 +73,6 @@ class login_signup_form extends moodleform {
 
         $mform->addElement('text', 'city', get_string('city'), 'maxlength="120" size="20"');
         $mform->setType('city', PARAM_TEXT);
-        $mform->addRule('city', get_string('missingcity'), 'required', null, 'server');
         if (!empty($CFG->defaultcity)) {
             $mform->setDefault('city', $CFG->defaultcity);
         }
@@ -82,7 +81,6 @@ class login_signup_form extends moodleform {
         $default_country[''] = get_string('selectacountry');
         $country = array_merge($default_country, $country);
         $mform->addElement('select', 'country', get_string('country'), $country);
-        $mform->addRule('country', get_string('missingcountry'), 'required', null, 'server');
 
         if( !empty($CFG->country) ){
             $mform->setDefault('country', $CFG->country);
index 0373e33..3d07191 100644 (file)
@@ -51,6 +51,7 @@ class backup_assign_activity_structure_step extends backup_activity_structure_st
                                                   'submissiondrafts',
                                                   'sendnotifications',
                                                   'sendlatenotifications',
+                                                  'sendstudentnotifications',
                                                   'duedate',
                                                   'cutoffdate',
                                                   'allowsubmissionsfromdate',
index 4cd7e49..7befb9c 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/assign/db" VERSION="20130314" COMMENT="XMLDB file for Moodle mod/assign"
+<XMLDB PATH="mod/assign/db" VERSION="20131220" COMMENT="XMLDB file for Moodle mod/assign"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
 >
@@ -32,6 +32,7 @@
         <FIELD NAME="maxattempts" TYPE="int" LENGTH="6" NOTNULL="true" DEFAULT="-1" SEQUENCE="false" COMMENT="What is the maximum number of student attempts allowed for this assignment? -1 means unlimited."/>
         <FIELD NAME="markingworkflow" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If enabled, marking workflow features will be used in this assignment."/>
         <FIELD NAME="markingallocation" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If enabled, marking allocation features will be used in this assignment"/>
+        <FIELD NAME="sendstudentnotifications" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Default for send student notifications checkbox when grading."/>
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="The unique id for this assignment instance."/>
       </INDEXES>
     </TABLE>
   </TABLES>
-</XMLDB>
+</XMLDB>
\ No newline at end of file
index b8e3eac..53142f0 100644 (file)
@@ -462,5 +462,27 @@ function xmldb_assign_upgrade($oldversion) {
     // Moodle v2.6.0 release upgrade line.
     // Put any upgrade step following this.
 
+    if ($oldversion < 2014010801) {
+
+        // Define field sendstudentnotifications to be added to assign.
+        $table = new xmldb_table('assign');
+        $field = new xmldb_field('sendstudentnotifications',
+                                 XMLDB_TYPE_INTEGER,
+                                 '2',
+                                 null,
+                                 XMLDB_NOTNULL,
+                                 null,
+                                 '1',
+                                 'markingallocation');
+
+        // Conditionally launch add field sendstudentnotifications.
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field);
+        }
+
+        // Assign savepoint reached.
+        upgrade_mod_savepoint(true, 2014010801, 'assign');
+    }
+
     return true;
 }
index cf582ce..fd28223 100644 (file)
@@ -312,11 +312,29 @@ class mod_assign_external extends external_api {
                 unset($courses[$id]);
             }
         }
-        $extrafields='m.id as assignmentid, m.course, m.nosubmissions, m.submissiondrafts, m.sendnotifications, '.
-                     'm.sendlatenotifications, m.duedate, m.allowsubmissionsfromdate, m.grade, m.timemodified, '.
-                     'm.completionsubmit, m.cutoffdate, m.teamsubmission, m.requireallteammemberssubmit, '.
-                     'm.teamsubmissiongroupingid, m.blindmarking, m.revealidentities, m.attemptreopenmethod, '.
-                     'm.maxattempts, m.markingworkflow, m.markingallocation, m.requiresubmissionstatement';
+        $extrafields='m.id as assignmentid, ' .
+                     'm.course, ' .
+                     'm.nosubmissions, ' .
+                     'm.submissiondrafts, ' .
+                     'm.sendnotifications, '.
+                     'm.sendlatenotifications, ' .
+                     'm.sendstudentnotifications, ' .
+                     'm.duedate, ' .
+                     'm.allowsubmissionsfromdate, '.
+                     'm.grade, ' .
+                     'm.timemodified, '.
+                     'm.completionsubmit, ' .
+                     'm.cutoffdate, ' .
+                     'm.teamsubmission, ' .
+                     'm.requireallteammemberssubmit, '.
+                     'm.teamsubmissiongroupingid, ' .
+                     'm.blindmarking, ' .
+                     'm.revealidentities, ' .
+                     'm.attemptreopenmethod, '.
+                     'm.maxattempts, ' .
+                     'm.markingworkflow, ' .
+                     'm.markingallocation, ' .
+                     'm.requiresubmissionstatement';
         $coursearray = array();
         foreach ($courses as $id => $course) {
             $assignmentarray = array();
@@ -359,6 +377,7 @@ class mod_assign_external extends external_api {
                         'submissiondrafts' => $module->submissiondrafts,
                         'sendnotifications' => $module->sendnotifications,
                         'sendlatenotifications' => $module->sendlatenotifications,
+                        'sendstudentnotifications' => $module->sendstudentnotifications,
                         'duedate' => $module->duedate,
                         'allowsubmissionsfromdate' => $module->allowsubmissionsfromdate,
                         'grade' => $module->grade,
@@ -412,6 +431,7 @@ class mod_assign_external extends external_api {
                 'submissiondrafts' => new external_value(PARAM_INT, 'submissions drafts'),
                 'sendnotifications' => new external_value(PARAM_INT, 'send notifications'),
                 'sendlatenotifications' => new external_value(PARAM_INT, 'send notifications'),
+                'sendstudentnotifications' => new external_value(PARAM_INT, 'send student notifications (default)'),
                 'duedate' => new external_value(PARAM_INT, 'assignment due date'),
                 'allowsubmissionsfromdate' => new external_value(PARAM_INT, 'allow submissions from date'),
                 'grade' => new external_value(PARAM_INT, 'grade type'),
index 2c61ed0..b677b20 100644 (file)
@@ -312,6 +312,10 @@ $string['savegradingresult'] = 'Grade';
 $string['saveallquickgradingchanges'] = 'Save all quick grading changes';
 $string['savenext'] = 'Save and show next';
 $string['scale'] = 'Scale';
+$string['sendstudentnotificationsdefault'] = 'Default setting for "Notify students"';
+$string['sendstudentnotificationsdefault_help'] = 'Set the default value for the "Notify students" checkbox on the grading form.';
+$string['sendstudentnotifications'] = 'Notify students';
+$string['sendstudentnotifications_help'] = 'If enabled, students receive a message about the updated grade or feedback.';
 $string['sendnotifications'] = 'Notify graders about submissions';
 $string['sendnotifications_help'] = 'If enabled, graders (usually teachers) receive a message whenever a student submits an assignment, early, on time and late. Message methods are configurable.';
 $string['selectlink'] = 'Select...';
index 2d5acfd..404b695 100644 (file)
@@ -538,6 +538,7 @@ class assign {
      */
     public function add_instance(stdClass $formdata, $callplugins) {
         global $DB;
+        $adminconfig = $this->get_admin_config();
 
         $err = '';
 
@@ -555,6 +556,10 @@ class assign {
         $update->requiresubmissionstatement = $formdata->requiresubmissionstatement;
         $update->sendnotifications = $formdata->sendnotifications;
         $update->sendlatenotifications = $formdata->sendlatenotifications;
+        $update->sendstudentnotifications = $adminconfig->sendstudentnotifications;
+        if (isset($formdata->sendstudentnotifications)) {
+            $update->sendstudentnotifications = $formdata->sendstudentnotifications;
+        }
         $update->duedate = $formdata->duedate;
         $update->cutoffdate = $formdata->cutoffdate;
         $update->allowsubmissionsfromdate = $formdata->allowsubmissionsfromdate;
@@ -878,6 +883,7 @@ class assign {
      */
     public function update_instance($formdata) {
         global $DB;
+        $adminconfig = $this->get_admin_config();
 
         $update = new stdClass();
         $update->id = $formdata->instance;
@@ -891,6 +897,10 @@ class assign {
         $update->requiresubmissionstatement = $formdata->requiresubmissionstatement;
         $update->sendnotifications = $formdata->sendnotifications;
         $update->sendlatenotifications = $formdata->sendlatenotifications;
+        $update->sendstudentnotifications = $adminconfig->sendstudentnotifications;
+        if (isset($formdata->sendstudentnotifications)) {
+            $update->sendstudentnotifications = $formdata->sendstudentnotifications;
+        }
         $update->duedate = $formdata->duedate;
         $update->cutoffdate = $formdata->cutoffdate;
         $update->allowsubmissionsfromdate = $formdata->allowsubmissionsfromdate;
@@ -3107,7 +3117,9 @@ class assign {
         if ($showquickgrading && $quickgrading) {
             $gradingtable = new assign_grading_table($this, $perpage, $filter, 0, true);
             $table = $this->get_renderer()->render($gradingtable);
-            $quickformparams = array('cm'=>$this->get_course_module()->id, 'gradingtable'=>$table);
+            $quickformparams = array('cm'=>$this->get_course_module()->id,
+                                     'gradingtable'=>$table,
+                                     'sendstudentnotifications'=>$this->get_instance()->sendstudentnotifications);
             $quickgradingform = new mod_assign_quick_grading_form(null, $quickformparams);
 
             $o .= $this->get_renderer()->render(new assign_form('quickgradingform', $quickgradingform));
@@ -4401,6 +4413,7 @@ class assign {
 
         $info = new stdClass();
         if ($blindmarking) {
+            $userfrom = clone($userfrom);
             $info->username = get_string('participant', 'assign') . ' ' . $uniqueidforuser;
             $userfrom->firstname = get_string('participant', 'assign');
             $userfrom->lastname = $uniqueidforuser;
@@ -4928,7 +4941,10 @@ class assign {
                 $this->update_user_flags($flags);
             }
             $this->update_grade($grade);
-            $this->notify_grade_modified($grade);
+            // Allow teachers to skip sending notifications.
+            if (optional_param('sendstudentnotifications', true, PARAM_BOOL)) {
+                $this->notify_grade_modified($grade);
+            }
 
             // Save outcomes.
             if ($CFG->enableoutcomes) {
@@ -5720,6 +5736,8 @@ class assign {
                 $mform->setDefault('addattempt', 0);
             }
         }
+        $mform->addElement('selectyesno', 'sendstudentnotifications', get_string('sendstudentnotifications', 'assign'));
+        $mform->setDefault('sendstudentnotifications', $this->get_instance()->sendstudentnotifications);
 
         $mform->addElement('hidden', 'action', 'submitgrade');
         $mform->setType('action', PARAM_ALPHA);
@@ -6215,7 +6233,11 @@ class assign {
             }
         }
         $this->update_grade($grade);
-        $this->notify_grade_modified($grade);
+        // Note the default if not provided for this option is true (e.g. webservices).
+        // This is for backwards compatibility.
+        if (!isset($formdata->sendstudentnotifications) || $formdata->sendstudentnotifications) {
+            $this->notify_grade_modified($grade);
+        }
 
         $addtolog = $this->add_to_log('grade submission', $this->format_grade_for_log($grade), '', true);
         $params = array(
index 1cd183c..eead2ae 100644 (file)
@@ -159,6 +159,10 @@ class mod_assign_mod_form extends moodleform_mod {
         $mform->addHelpButton('sendlatenotifications', 'sendlatenotifications', 'assign');
         $mform->disabledIf('sendlatenotifications', 'sendnotifications', 'eq', 1);
 
+        $name = get_string('sendstudentnotificationsdefault', 'assign');
+        $mform->addElement('selectyesno', 'sendstudentnotifications', $name);
+        $mform->addHelpButton('sendstudentnotifications', 'sendstudentnotificationsdefault', 'assign');
+
         // Plagiarism enabling form.
         if (!empty($CFG->enableplagiarism)) {
             require_once($CFG->libdir . '/plagiarismlib.php');
index 2e93df7..bff0294 100644 (file)
@@ -52,6 +52,10 @@ class mod_assign_quick_grading_form extends moodleform {
         $mform->addElement('hidden', 'action', 'quickgrade');
         $mform->setType('action', PARAM_ALPHA);
 
+        // Skip notifications option.
+        $mform->addElement('selectyesno', 'sendstudentnotifications', get_string('sendstudentnotifications', 'assign'));
+        $mform->setDefault('sendstudentnotifications', $instance['sendstudentnotifications']);
+
         // Buttons.
         $savemessage = get_string('saveallquickgradingchanges', 'assign');
         $mform->addElement('submit', 'savequickgrades', $savemessage);
index 04575f4..c923788 100644 (file)
@@ -213,6 +213,16 @@ if ($ADMIN->fulltree) {
     $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
     $settings->add($setting);
 
+    $name = new lang_string('sendstudentnotificationsdefault', 'mod_assign');
+    $description = new lang_string('sendstudentnotificationsdefault_help', 'mod_assign');
+    $setting = new admin_setting_configcheckbox('assign/sendstudentnotifications',
+                                                    $name,
+                                                    $description,
+                                                    1);
+    $setting->set_advanced_flag_options(admin_setting_flag::ENABLED, false);
+    $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
+    $settings->add($setting);
+
     $name = new lang_string('blindmarking', 'mod_assign');
     $description = new lang_string('blindmarking_help', 'mod_assign');
     $setting = new admin_setting_configcheckbox('assign/blindmarking',
index 2e88966..07600d8 100644 (file)
@@ -34,6 +34,7 @@ class mod_assign_generator extends testing_module_generator {
             'submissiondrafts'                  => 1,
             'requiresubmissionstatement'        => 0,
             'sendnotifications'                 => 0,
+            'sendstudentnotifications'          => 1,
             'sendlatenotifications'             => 0,
             'duedate'                           => 0,
             'allowsubmissionsfromdate'          => 0,
index 77c0897..a1ca542 100644 (file)
@@ -527,7 +527,7 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
 
         // Now create an assignment and add some feedback.
         $this->setUser($this->editingteachers[0]);
-        $assign = $this->create_instance();
+        $assign = $this->create_instance(array('sendstudentnotifications'=>1));
 
         // Simulate adding a grade.
         $this->setUser($this->teachers[0]);
@@ -536,6 +536,9 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
         $assign->testable_apply_grade_to_user($data, $this->students[0]->id, 0);
         $assign->testable_apply_grade_to_user($data, $this->students[1]->id, 0);
 
+        $data->sendstudentnotifications = false;
+        $assign->testable_apply_grade_to_user($data, $this->students[2]->id, 0);
+
         // Now run cron and see that one message was sent.
         $this->preventResetByRollback();
         $sink = $this->redirectMessages();
@@ -544,6 +547,7 @@ class mod_assign_locallib_testcase extends mod_assign_base_testcase {
         assign::cron();
 
         $messages = $sink->get_messages();
+        // The sent count should be 2, because the 3rd one was marked as do not send notifications.
         $this->assertEquals(2, count($messages));
         $this->assertEquals(1, $messages[0]->notification);
         $this->assertEquals($assign->get_instance()->name, $messages[0]->contexturlname);
index 2c71b5c..7de1d26 100644 (file)
@@ -53,15 +53,13 @@ class mod_assign_upgradelib_testcase extends mod_assign_base_testcase {
         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assignment');
         $params = array('course'=>$this->course->id,
                         'assignmenttype'=>'upload');
-        $record = $generator->create_instance($params);
-
-        $assignment = new assignment_base($record->cmid);
+        $assignment = $generator->create_instance($params);
 
         $this->setAdminUser();
         $log = '';
         $upgrader = new assign_upgrade_manager();
 
-        $this->assertTrue($upgrader->upgrade_assignment($assignment->assignment->id, $log));
+        $this->assertTrue($upgrader->upgrade_assignment($assignment->id, $log));
         $record = $DB->get_record('assign', array('course'=>$this->course->id));
 
         $cm = get_coursemodule_from_instance('assign', $record->id);
@@ -99,15 +97,13 @@ class mod_assign_upgradelib_testcase extends mod_assign_base_testcase {
         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assignment');
         $params = array('course'=>$this->course->id,
                         'assignmenttype'=>'uploadsingle');
-        $record = $generator->create_instance($params);
-
-        $assignment = new assignment_base($record->cmid);
+        $assignment = $generator->create_instance($params);
 
         $this->setAdminUser();
         $log = '';
         $upgrader = new assign_upgrade_manager();
 
-        $this->assertTrue($upgrader->upgrade_assignment($assignment->assignment->id, $log));
+        $this->assertTrue($upgrader->upgrade_assignment($assignment->id, $log));
         $record = $DB->get_record('assign', array('course'=>$this->course->id));
 
         $cm = get_coursemodule_from_instance('assign', $record->id);
@@ -145,15 +141,13 @@ class mod_assign_upgradelib_testcase extends mod_assign_base_testcase {
         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assignment');
         $params = array('course'=>$this->course->id,
                         'assignmenttype'=>'online');
-        $record = $generator->create_instance($params);
-
-        $assignment = new assignment_base($record->cmid);
+        $assignment = $generator->create_instance($params);
 
         $this->setAdminUser();
         $log = '';
         $upgrader = new assign_upgrade_manager();
 
-        $this->assertTrue($upgrader->upgrade_assignment($assignment->assignment->id, $log));
+        $this->assertTrue($upgrader->upgrade_assignment($assignment->id, $log));
         $record = $DB->get_record('assign', array('course'=>$this->course->id));
 
         $cm = get_coursemodule_from_instance('assign', $record->id);
@@ -191,15 +185,13 @@ class mod_assign_upgradelib_testcase extends mod_assign_base_testcase {
         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assignment');
         $params = array('course'=>$this->course->id,
                         'assignmenttype'=>'offline');
-        $record = $generator->create_instance($params);
-
-        $assignment = new assignment_base($record->cmid);
+        $assignment = $generator->create_instance($params);
 
         $this->setAdminUser();
         $log = '';
         $upgrader = new assign_upgrade_manager();
 
-        $this->assertTrue($upgrader->upgrade_assignment($assignment->assignment->id, $log));
+        $this->assertTrue($upgrader->upgrade_assignment($assignment->id, $log));
         $record = $DB->get_record('assign', array('course'=>$this->course->id));
 
         $cm = get_coursemodule_from_instance('assign', $record->id);
index 601d8b5..ec94096 100644 (file)
@@ -1,4 +1,7 @@
 This files describes API changes in the assign code.
+=== 2.7 ===
+* Added setting sendstudentnotifications to assign DB table with admin defaults. This sets the default value for the
+  "Notify students" option on the grading forms. This setting can be retrieved via webservices.
 
 === 2.6.1 ===
 
index 1b26b56..aef0f14 100644 (file)
@@ -299,6 +299,15 @@ class assign_upgrade_manager {
             $sql = 'UPDATE {grade_items} SET itemmodule = ?, iteminstance = ? WHERE itemmodule = ? AND iteminstance = ?';
             $DB->execute($sql, $params);
 
+            // Create a mapping record to map urls from the old to the new assignment.
+            $mapping = new stdClass();
+            $mapping->oldcmid = $oldcoursemodule->id;
+            $mapping->oldinstance = $oldassignment->id;
+            $mapping->newcmid = $newcoursemodule->id;
+            $mapping->newinstance = $newassignment->get_instance()->id;
+            $mapping->timecreated = time();
+            $DB->insert_record('assignment_upgrade', $mapping);
+
             $gradesdone = true;
 
         } catch (Exception $exception) {
index 60a2aa6..a2e1f9a 100644 (file)
@@ -25,7 +25,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $module->component = 'mod_assign'; // Full name of the plugin (used for diagnostics).
-$module->version  = 2014010700;    // The current module version (Date: YYYYMMDDXX).
+$module->version  = 2014010801;    // The current module version (Date: YYYYMMDDXX).
 $module->requires = 2013110500;    // Requires this Moodle version.
 $module->cron     = 60;
 
diff --git a/mod/assignment/assignment.js b/mod/assignment/assignment.js
deleted file mode 100644 (file)
index 07c1af3..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-var assignment = {};
-
-function setNext(){
-    document.getElementById('submitform').mode.value = 'next';
-    document.getElementById('submitform').userid.value = assignment.nextid;
-}
-
-function saveNext(){
-    document.getElementById('submitform').mode.value = 'saveandnext';
-    document.getElementById('submitform').userid.value = assignment.nextid;
-    document.getElementById('submitform').saveuserid.value = assignment.userid;
-    document.getElementById('submitform').menuindex.value = document.getElementById('submitform').grade.selectedIndex;
-}
-
-function initNext(nextid, usserid) {
-    assignment.nextid = nextid;
-    assignment.userid = userid;
-}
-
-M.mod_assignment = {};
-
-M.mod_assignment.init_tree = function(Y, expand_all, htmlid) {
-    Y.use('yui2-treeview', function(Y) {
-        var tree = new Y.YUI2.widget.TreeView(htmlid);
-
-        tree.subscribe("clickEvent", function(node, event) {
-            // we want normal clicking which redirects to url
-            return false;
-        });
-
-        if (expand_all) {
-            tree.expandAll();
-        }
-
-        tree.render();
-    });
-};
-
-M.mod_assignment.init_grade_change = function(Y) {
-    var gradenode = Y.one('#id_grade');
-    if (gradenode) {
-        var originalvalue = gradenode.get('value');
-        gradenode.on('change', function() {
-            if (gradenode.get('value') != originalvalue) {
-                alert(M.str.mod_assignment.changegradewarning);
-            }
-        });
-    }
-};
index e5d8a7f..072e87f 100644 (file)
@@ -109,4 +109,13 @@ class restore_assignment_activity_task extends restore_activity_task {
 
         return $rules;
     }
+
+    /**
+     * Expose the restore mode so we can skip automatic upgrade for MODE_IMPORT (e.g. duplicate).
+     *
+     * @return int
+     */
+    public function get_mode() {
+        return $this->plan->get_mode();
+    }
 }
index b7f8f56..11ee37d 100644 (file)
@@ -98,6 +98,46 @@ class restore_assignment_activity_structure_step extends restore_activity_struct
         $this->set_mapping(restore_gradingform_plugin::itemid_mapping('submission'), $oldid, $newitemid);
     }
 
+    /**
+     * This function will attempt to upgrade the newly restored assignment to an instance of mod_assign if
+     * mod_assignment is currently disabled and mod_assign is enabled and mod_assign says it can upgrade this assignment.
+     *
+     * @return none
+     */
+    private function upgrade_mod_assign() {
+        global $DB, $CFG;
+
+        // The current module must exist.
+        $pluginmanager = core_plugin_manager::instance();
+
+        $plugininfo = $pluginmanager->get_plugin_info('mod_assign');
+
+        // Check that the assignment module is installed.
+        if ($plugininfo && $plugininfo->is_installed_and_upgraded()) {
+            // Include the required mod assign upgrade code.
+            require_once($CFG->dirroot . '/mod/assign/upgradelib.php');
+            require_once($CFG->dirroot . '/mod/assign/locallib.php');
+
+            // Get the id and type of this assignment.
+            $newinstance = $this->task->get_activityid();
+
+            $record = $DB->get_record('assignment', array('id'=>$newinstance), 'assignmenttype', MUST_EXIST);
+            $type = $record->assignmenttype;
+
+            $subplugininfo = $pluginmanager->get_plugin_info('assignment_' . $type);
+
+            // See if it is possible to upgrade.
+            if (assign::can_upgrade_assignment($type, $subplugininfo->versiondb)) {
+                $assignment_upgrader = new assign_upgrade_manager();
+                $log = '';
+                $success = $assignment_upgrader->upgrade_assignment($newinstance, $log);
+                if (!$success) {
+                    throw new restore_step_exception('mod_assign_upgrade_failed', $log);
+                }
+            }
+        }
+    }
+
     protected function after_execute() {
         // Add assignment related files, no need to match by itemname (just internally handled context)
         $this->add_related_files('mod_assignment', 'intro', null);
@@ -106,6 +146,17 @@ class restore_assignment_activity_structure_step extends restore_activity_struct
         $this->add_related_files('mod_assignment', 'response', 'assignment_submission');
     }
 
+    /**
+     * Hook to execute assignment upgrade after restore.
+     */
+    protected function after_restore() {
+
+        if ($this->get_task()->get_mode() != backup::MODE_IMPORT) {
+            // Moodle 2.2 assignment upgrade
+            $this->upgrade_mod_assign();
+        }
+    }
+
     /**
      * Determine if a sub-plugin is supported or not
      *
index e76cc0a..656a963 100644 (file)
@@ -29,7 +29,17 @@ defined('MOODLE_INTERNAL') || die();
 
 
 class assignment extends base {
-    public function is_uninstall_allowed() {
+    /**
+     * Returns the information about plugin availability
+     *
+     * True means that the plugin is enabled. False means that the plugin is
+     * disabled. Null means that the information is not available, or the
+     * plugin does not support configurable availability or the availability
+     * can not be changed.
+     *
+     * @return null|bool
+     */
+    public function is_enabled() {
         return false;
     }
 }
index c517366..a820de3 100644 (file)
         <INDEX NAME="timemarked" UNIQUE="false" FIELDS="timemarked"/>
       </INDEXES>
     </TABLE>
+    <TABLE NAME="assignment_upgrade" COMMENT="Info about upgraded assignments">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
+        <FIELD NAME="oldcmid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
+        <FIELD NAME="oldinstance" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
+        <FIELD NAME="newcmid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
+        <FIELD NAME="newinstance" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
+        <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="oldcmid" UNIQUE="false" FIELDS="oldcmid"/>
+        <INDEX NAME="oldinstance" UNIQUE="false" FIELDS="oldinstance"/>
+      </INDEXES>
+    </TABLE>
   </TABLES>
-</XMLDB>
\ No newline at end of file
+</XMLDB>
index cc74faf..a6c69cd 100644 (file)
@@ -23,8 +23,9 @@
 function xmldb_assignment_upgrade($oldversion) {
     global $CFG, $DB, $OUTPUT;
 
-    $dbman = $DB->get_manager();
+    require_once(__DIR__.'/upgradelib.php');
 
+    $dbman = $DB->get_manager();
 
     // Moodle v2.2.0 release upgrade line
     // Put any upgrade step following this
@@ -81,6 +82,55 @@ function xmldb_assignment_upgrade($oldversion) {
     // Moodle v2.6.0 release upgrade line.
     // Put any upgrade step following this.
 
+    if ($oldversion < 2013121900) {
+        // Define table assignment_upgrade to be created.
+        $table = new xmldb_table('assignment_upgrade');
+
+        // Adding fields to table assignment_upgrade.
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('oldcmid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
+        $table->add_field('oldinstance', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
+        $table->add_field('newcmid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
+        $table->add_field('newinstance', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
+        $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
+
+        // Adding keys to table assignment_upgrade.
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+
+        // Adding indexes to table assignment_upgrade.
+        $table->add_index('oldcmid', XMLDB_INDEX_NOTUNIQUE, array('oldcmid'));
+        $table->add_index('oldinstance', XMLDB_INDEX_NOTUNIQUE, array('oldinstance'));
+
+        // Conditionally launch create table for assignment_upgrade.
+        if (!$dbman->table_exists($table)) {
+            $dbman->create_table($table);
+        }
+
+        if ($module = $DB->get_record("modules", array("name" => "assignment"))) {
+            $DB->set_field("modules", "visible", "0", array("id" => $module->id)); // Hide module.
+            // Hide all course modules.
+            $sql = "UPDATE {course_modules}
+                       SET visibleold = visible, visible = 0
+                     WHERE module = ?";
+            $DB->execute($sql, array($module->id));
+            // Increment course.cacherev for courses where we just made something invisible.
+            // This will force cache rebuilding on the next request.
+            increment_revision_number('course', 'cacherev',
+                    "id IN (SELECT DISTINCT course
+                                    FROM {course_modules}
+                                   WHERE visibleold = 1 AND module = ?)",
+                    array($module->id));
+        }
+
+        $count = $DB->count_records('assignment');
+        if ($count) {
+            mod_assignment_pending_upgrades_notification($count);
+        }
+
+        // Assignment savepoint reached.
+        upgrade_mod_savepoint(true, 2013121900, 'assignment');
+    }
+
     return true;
 }
 
diff --git a/mod/assignment/db/upgradelib.php b/mod/assignment/db/upgradelib.php
new file mode 100644 (file)
index 0000000..d245d35
--- /dev/null
@@ -0,0 +1,54 @@
+<?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/>.
+
+/**
+ * Assignment upgrade script.
+ *
+ * @package   mod_assignment
+ * @copyright 2013 Damyon Wiese
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Inform admins about assignments that still need upgrading.
+ */
+function mod_assignment_pending_upgrades_notification($count) {
+    $admins = get_admins();
+
+    if (empty($admins)) {
+        return;
+    }
+
+    $a = new stdClass;
+    $a->count = $count;
+    $a->docsurl = get_docs_url('Assignment_upgrade_tool');
+    foreach ($admins as $admin) {
+        $message = new stdClass();
+        $message->component         = 'moodle';
+        $message->name              = 'notices';
+        $message->userfrom          = \core_user::get_noreply_user();
+        $message->userto            = $admin;
+        $message->smallmessage      = get_string('pendingupgrades_message_small', 'mod_assignment');
+        $message->subject           = get_string('pendingupgrades_message_subject', 'mod_assignment');
+        $message->fullmessage       = get_string('pendingupgrades_message_content', 'mod_assignment', $a);
+        $message->fullmessagehtml   = get_string('pendingupgrades_message_content', 'mod_assignment', $a);
+        $message->fullmessageformat = FORMAT_PLAIN;
+        $message->notification      = 1;
+        message_send($message);
+    }
+}
diff --git a/mod/assignment/delete.php b/mod/assignment/delete.php
deleted file mode 100644 (file)
index c5cbea7..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-
-require_once('../../config.php');
-require_once('lib.php');
-
-$id = optional_param('id', 0, PARAM_INT);  // Course module ID
-$a  = optional_param('a', 0, PARAM_INT);   // Assignment ID
-
-$url = new moodle_url('/mod/assignment/delete.php');
-if ($id) {
-    if (! $cm = get_coursemodule_from_id('assignment', $id)) {
-        print_error('invalidcoursemodule');
-    }
-
-    if (! $assignment = $DB->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);
-}
-
-$PAGE->set_url($url);
-require_login($course, false, $cm);
-
-/// 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->delete();   // delete something
\ No newline at end of file
diff --git a/mod/assignment/grade.php b/mod/assignment/grade.php
deleted file mode 100644 (file)
index 543b762..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-<?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/>.
-
-/**
- * Redirect the user to the appropriate submission related page within /mod/assignment
- *
- * Based on the supplied parameters and the user's capabilities the user will be redirected
- * to either their own submission, a particular student's submission or a summary of all submissions
- *
- * @package   mod_assignment
- * @category  grade
- * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-require_once("../../config.php");
-
-$id   = required_param('id', PARAM_INT);          // Course module ID
-$userid = optional_param('userid', 0, PARAM_INT); // Graded user ID (optional)
-
-$PAGE->set_url('/mod/assignment/grade.php', array('id'=>$id));
-if (! $cm = get_coursemodule_from_id('assignment', $id)) {
-    print_error('invalidcoursemodule');
-}
-
-if (! $assignment = $DB->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');
-}
-
-require_login($course, false, $cm);
-
-if (has_capability('mod/assignment:grade', context_module::instance($cm->id))) {
-    if ($userid) {
-        redirect('submissions.php?id='.$cm->id.'&userid='.$userid.'&mode=single&filter=0&offset=0');
-    } else {
-        redirect('submissions.php?id='.$cm->id);
-    }
-} else {
-    // user will view his own submission, parameter $userid is ignored
-    redirect('view.php?id='.$cm->id);
-}
index ad94134..9e0c70c 100644 (file)
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$string['activityoverview'] = 'You have assignments that need attention';
-$string['allowdeleting'] = 'Allow deleting';
-$string['allowdeleting_help'] = 'If enabled, students may delete uploaded files at any time before submitting for grading.';
-$string['allowmaxfiles'] = 'Maximum number of uploaded files';
-$string['allowmaxfiles_help'] = 'The maximum number of files which may be uploaded. As this figure is not displayed anywhere, it is suggested that it is mentioned in the assignment description.';
-$string['allownotes'] = 'Allow notes';
-$string['allownotes_help'] = 'If enabled, students may enter notes into a text area, as in an online text assignment.';
-$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['assignment:addinstance'] = 'Add a new assignment';
-$string['assignmentdetails'] = 'Assignment details';
 $string['assignment:exportownsubmission'] = 'Export own submission';
 $string['assignment:exportsubmission'] = 'Export submission';
 $string['assignment:grade'] = 'Grade assignment';
-$string['assignmentmail'] = '{$a->teacher} has posted some feedback on your
-assignment submission for \'{$a->assignment}\'
-
-You can see it appended to your assignment submission:
-
-    {$a->url}';
-$string['assignmentmailhtml'] = '<p>{$a->teacher} has posted some feedback on your
-assignment submission for \'<i>{$a->assignment}</i>\'.</p>
-<p>You can see it appended to your <a href="{$a->url}">assignment submission</a>.</p>';
-$string['assignmentmailsmall'] = '{$a->teacher} has posted some feedback on your
-assignment submission for \'{$a->assignment}\' You can see it appended to your submission';
-$string['assignmentname'] = 'Assignment name';
 $string['assignment:submit'] = 'Submit assignment';
-$string['assignmentsubmission'] = 'Assignment submissions';
-$string['assignmenttype'] = 'Assignment type';
 $string['assignment:view'] = 'View assignment';
-$string['availabledate'] = 'Available from';
-$string['cannotdeletefiles'] = 'An error occurred and files could not be deleted';
-$string['cannotviewassignment'] = 'You can not view this assignment';
-$string['changegradewarning'] = 'This assignment has graded submissions and changing the grade will not automatically re-calculate existing submission grades. You must re-grade all existing submissions, if you wish to change the grade.';
-$string['closedassignment'] = 'This assignment is closed, as the submission deadline has passed.';
-$string['comment'] = 'Comment';
-$string['commentinline'] = 'Comment inline';
-$string['commentinline_help'] = 'If enabled, the submission text will be copied into the feedback comment field during grading, making it easier to comment inline (using a different colour, perhaps) or to edit the original text.';
-$string['configitemstocount'] = 'Nature of items to be counted for student submissions in online assignments.';
-$string['configmaxbytes'] = 'Default maximum assignment size for all assignments on the site (subject to course limits and other local settings)';
-$string['configshowrecentsubmissions'] = 'Everyone can see notifications of submissions in recent activity reports.';
-$string['confirmdeletefile'] = 'Are you absolutely sure you want to delete this file?<br /><strong>{$a}</strong>';
-$string['coursemisconf'] = 'Course is misconfigured';
-$string['currentgrade'] = 'Current grade in gradebook';
-$string['deleteallsubmissions'] = 'Delete all submissions';
-$string['deletefilefailed'] = 'Deleting of file failed.';
-$string['description'] = 'Description';
-$string['downloadall'] = 'Download all assignments as a zip';
-$string['draft'] = 'Draft';
-$string['due'] = 'Assignment due';
-$string['duedate'] = 'Due date';
-$string['duedateno'] = 'No due date';
-$string['early'] = '{$a} early';
-$string['editmysubmission'] = 'Edit my submission';
-$string['editthesefiles'] = 'Edit these files';
-$string['editthisfile'] = 'Update this file';
-$string['addsubmission'] = 'Add submission';
-$string['emailstudents'] = 'Email alerts to students';
-$string['emailteachermail'] = '{$a->username} has updated their assignment submission
-for \'{$a->assignment}\' at {$a->timeupdated}
-
-It is available here:
-
-    {$a->url}';
-$string['emailteachermailhtml'] = '<p>{$a->username} has updated their assignment submission for <i>\'{$a->assignment}\' at {$a->timeupdated}</i>.</p>
-<p>It is <a href="{$a->url}">available on the site</a>.</p>';
-$string['emailteachers'] = 'Email alerts to teachers';
-$string['emailteachers_help'] = 'If enabled, teachers receive email notification whenever students add or update an assignment submission.
-
-Only teachers who are able to grade the particular assignment are notified. So, for example, if the course uses separate groups, teachers restricted to particular groups won\'t receive notification about students in other groups.';
-$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['errornosubmissions'] = 'There are no submissions to download';
-$string['existingfiledeleted'] = 'Existing file has been deleted: {$a}';
-$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['finalizeerror'] = 'An error occurred and that submission could not be finalised';
-$string['futureaassignment'] = 'This assignment is not yet available.';
-$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.';
-$string['guestnoupload'] = 'Sorry, guests are not allowed to upload';
-$string['helpoffline'] = '<p>This is useful when the assignment is performed outside of Moodle.  It could be
-   something elsewhere on the web or face-to-face.</p><p>Students can see a description of the assignment,
-   but can\'t upload files or anything.  Grading works normally, and students will get notifications of
-   their grades.</p>';
-$string['helponline'] = '<p>This assignment type asks users to edit a text, using the normal
-   editing tools.  Teachers can grade them online, and even add inline comments or changes.</p>
-   <p>(If you are familiar with older versions of Moodle, this Assignment
-   type does the same thing as the old Journal module used to do.)</p>';
-$string['helpupload'] = '<p>This type of assignment allows each participant to upload one or more files in any format.
-   These might be a Word processor documents, images, a zipped web site, or anything you ask them to submit.</p>
-   <p>This type also allows you to upload multiple response files. Response files can be also uploaded before submission which
-   can be used to give each participant different file to work with.</p>
-   <p>Participants may also enter notes describing the submitted files, progress status or any other text information.</p>
-   <p>Submission of this type of assignment must be manually finalised by the participant. You can review the current status
-   at any time, unfinished assignments are marked as Draft. You can revert any ungraded assignment back to draft status.</p>';
-$string['helpuploadsingle'] = '<p>This type of assignment allows each participant to upload a
-   single file, of any type.</p> <p>This might be a Word processor document, an image,
-   a zipped web site, or anything you ask them to submit.</p>';
-$string['hideintro'] = 'Hide description before available date';
-$string['hideintro_help'] = 'If enabled, the assignment description is hidden before the "Available from" date. Only the assignment name is displayed.';
-$string['invalidassignment'] = 'Invalid assignment';
-$string['invalidfileandsubmissionid'] = 'Missing file or submission ID';
-$string['invalidid'] = 'Invalid assignment ID';
-$string['invalidsubmissionid'] = 'Invalid submission ID';
-$string['invalidtype'] = 'Invalid assignment type';
-$string['invaliduserid'] = 'Invalid user ID';
-$string['itemstocount'] = 'Count';
-$string['lastgrade'] = 'Last grade';
-$string['late'] = '{$a} late';
-$string['maximumgrade'] = 'Maximum grade';
-$string['maximumsize'] = 'Maximum size';
-$string['maxpublishstate'] = 'Maximum visibility for blog entry before due date';
+$string['assignmentneedsupgrade'] = 'The legacy "Assignment 2.2" activity has been disabled. Please request that your site administrator runs the assignment upgrade tool for all legacy assignments in this site.';
 $string['messageprovider:assignment_updates'] = 'Assignment (2.2) notifications';
-$string['modulename'] = 'Assignment (2.2)';
-$string['modulename_help'] = 'Assignments enable the teacher to specify a task either on or offline which can then be graded.';
-$string['modulenameplural'] = 'Assignments (2.2)';
-$string['newsubmissions'] = 'Assignments submitted';
-$string['noassignments'] = 'There are no assignments yet';
-$string['noattempts'] = 'No attempts have been made on this assignment';
-$string['noblogs'] = 'You have no blog entries to submit!';
-$string['nofiles'] = 'No files were submitted';
-$string['nofilesyet'] = 'No files submitted yet';
-$string['nomoresubmissions'] = 'No further submissions are allowed.';
-$string['notavailableyet'] = 'Sorry, this assignment is not yet available.<br />Assignment instructions will be displayed here on the date given below.';
-$string['notes'] = 'Notes';
-$string['notesempty'] = 'No entry';
-$string['notesupdateerror'] = 'Error when updating notes';
-$string['notgradedyet'] = 'Not graded yet';
-$string['norequiregrading'] = 'There are no assignments that require grading';
-$string['nosubmisson'] = 'No assignments have been submit';
-$string['notsubmittedyet'] = 'Not submitted yet';
-$string['onceassignmentsent'] = 'Once the assignment is sent for marking, you will no longer be able to delete or attach file(s). Do you want to continue?';
-$string['operation'] = 'Operation';
-$string['optionalsettings'] = 'Optional settings';
-$string['overwritewarning'] = 'Warning: uploading again will REPLACE your current submission';
+$string['assignmentdisabled'] = 'The legacy "Assignment 2.2" activity is disabled.';
+$string['modulename'] = 'Assignment 2.2 (Disabled)';
+$string['modulename_help'] = 'Legacy activity module that has been removed from Moodle.';
+$string['modulenameplural'] = 'Assignments 2.2 (Disabled)';
 $string['page-mod-assignment-x'] = 'Any assignment module page';
 $string['page-mod-assignment-view'] = 'Assignment module main page';
 $string['page-mod-assignment-submissions'] = 'Assignment module submission page';
-$string['pagesize'] = 'Submissions shown per page';
-$string['popupinnewwindow'] = 'Open in a popup window';
-$string['pluginadministration'] = 'Assignment administration';
-$string['pluginname'] = 'Assignment (2.2)';
-$string['preventlate'] = 'Prevent late submissions';
-$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['responsefiles'] = 'Response files';
-$string['reviewed'] = 'Reviewed';
-$string['saveallfeedback'] = 'Save all my feedback';
-$string['selectblog'] = 'Select which blog entry you wish to submit';
-$string['sendformarking'] = 'Send for marking';
-$string['showrecentsubmissions'] = 'Show recent submissions';
-$string['submission'] = 'Submission';
-$string['submissiondraft'] = 'Submission draft';
-$string['submissionfeedback'] = 'Submission feedback';
-$string['submissions'] = 'Submissions';
-$string['submissionsaved'] = 'Your changes have been saved';
-$string['submissionsnotgraded'] = '{$a} submissions not graded';
-$string['submitassignment'] = 'Submit your assignment using this form';
-$string['submitedformarking'] = 'Assignment was already submitted for marking and can not be updated';
-$string['submitformarking'] = 'Final submission for assignment marking';
-$string['submitted'] = 'Submitted';
-$string['submittedfiles'] = 'Submitted files';
-$string['subplugintype_assignment'] = 'Assignment type';
-$string['subplugintype_assignment_plural'] = 'Assignment types';
-$string['trackdrafts'] = 'Enable "Send for marking" button';
-$string['trackdrafts_help'] = 'The "Send for marking" button allows students to indicate to the teacher that they have finished working on an assignment. The teacher may choose to revert the assignment to draft status (if it requires further work, for example).';
-$string['typeblog'] = 'Blog post';
-$string['typeoffline'] = 'Offline activity';
-$string['typeonline'] = 'Online text';
-$string['typeupload'] = 'Advanced uploading of files';
-$string['typeuploadsingle'] = 'Upload a single file';
-$string['unfinalize'] = 'Revert to draft';
-$string['unfinalize_help'] = 'Reverting to draft enables the student to make further updates to their assignment';
-$string['unfinalizeerror'] = 'An error occurred and that submission could not be reverted to draft';
+$string['pluginname'] = 'Assignment 2.2 (Disabled)';
 $string['upgradenotification'] = 'This activity is based on an older assignment module.';
-$string['uploadafile'] = 'Upload a file';
-$string['uploadfiles'] = 'Upload files';
-$string['uploadbadname'] = 'This filename contained strange characters and couldn\'t be uploaded';
-$string['uploadedfiles'] = 'uploaded files';
-$string['uploaderror'] = 'An error happened while saving the file on the server';
-$string['uploadfailnoupdate'] = 'File was uploaded OK but could not update your submission!';
-$string['uploadfiletoobig'] = 'Sorry, but that file is too big (limit is {$a} bytes)';
-$string['uploadnofilefound'] = 'No file was found - are you sure you selected one to upload?';
-$string['uploadnotregistered'] = '\'{$a}\' was uploaded OK but submission did not register!';
-$string['uploadsuccess'] = 'Uploaded \'{$a}\' successfully';
-$string['usermisconf'] = 'User is misconfigured';
-$string['usernosubmit'] = 'Sorry, you are not allowed to submit an assignment.';
 $string['viewassignmentupgradetool'] = 'View the assignment upgrade tool';
-$string['viewfeedback'] = 'View assignment grades and feedback';
-$string['viewmysubmission'] = 'View my submission';
-$string['viewsubmissions'] = 'View {$a} submitted assignments';
-$string['yoursubmission'] = 'Your submission';
-$string['unsupportedsubplugin'] = 'The assignment type of \'{$a}\' is not currently supported. You may wait until the assignment type is made available, or delete the assignment.';
+$string['pendingupgrades_message_small'] = 'This plugin has been disabled. All remaining assignments must be upgraded to the new assignment module using the assignment upgrade tool.';
+$string['pendingupgrades_message_subject'] = 'Important information regarding Assignment 2.2';
+$string['pendingupgrades_message_content'] = 'As part of the upgrade to Moodle 2.7, the legacy Assignment 2.2 activity has been disabled. Backups from the legacy Assignment 2.2 activity will seamlessly restore to the newer Assignment activity. All remaining instances of the legacy Assignment 2.2 activity must be upgraded using the assignment upgrade tool {$a->docsurl}. There are {$a->count} instances of the legacy Assignment 2.2 activity on this site that require upgrading. Users will not be able to access the content of these activities until they have been upgraded.';
+$string['pluginadministration'] = 'Assignment 2.2 (Disabled) administration';
index 5bf9d03..bd90f8b 100644 (file)
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-/** Include eventslib.php */
-require_once($CFG->libdir.'/eventslib.php');
-/** Include formslib.php */
-require_once($CFG->libdir.'/formslib.php');
-/** Include calendar/lib.php */
-require_once($CFG->dirroot.'/calendar/lib.php');
-
-/** ASSIGNMENT_COUNT_WORDS = 1 */
-define('ASSIGNMENT_COUNT_WORDS', 1);
-/** ASSIGNMENT_COUNT_LETTERS = 2 */
-define('ASSIGNMENT_COUNT_LETTERS', 2);
-
-/**
- * Standard base class for all assignment submodules (assignment types).
- *
- * @package   mod-assignment
- * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class assignment_base {
-
-    const FILTER_ALL             = 0;
-    const FILTER_SUBMITTED       = 1;
-    const FILTER_REQUIRE_GRADING = 2;
-
-    /** @var object */
-    var $cm;
-    /** @var object */
-    var $course;
-    /** @var stdClass */
-    var $coursecontext;
-    /** @var object */
-    var $assignment;
-    /** @var string */
-    var $strassignment;
-    /** @var string */
-    var $strassignments;
-    /** @var string */
-    var $strsubmissions;
-    /** @var string */
-    var $strlastmodified;
-    /** @var string */
-    var $pagetitle;
-    /**
-     * @todo document this var
-     */
-    var $defaultformat;
-    /**
-     * @todo document this var
-     */
-    var $context;
-    /** @var string */
-    var $type;
-
-    /**
-     * Constructor for the base assignment class
-     *
-     * Constructor for the base assignment class.
-     * If cmid is set create the cm, course, assignment objects.
-     * If the assignment is hidden and the user is not a teacher then
-     * this prints a page header and notice.
-     *
-     * @global object
-     * @global object
-     * @param int $cmid the current course module id - not set for new assignments
-     * @param object $assignment usually null, but if we have it we pass it to save db access
-     * @param object $cm usually null, but if we have it we pass it to save db access
-     * @param object $course usually null, but if we have it we pass it to save db access
-     */
-    function assignment_base($cmid='staticonly', $assignment=NULL, $cm=NULL, $course=NULL) {
-        global $COURSE, $DB;
-
-        if ($cmid == 'staticonly') {
-            //use static functions only!
-            return;
-        }
-
-        global $CFG;
-
-        if ($cm) {
-            $this->cm = $cm;
-        } else if (! $this->cm = get_coursemodule_from_id('assignment', $cmid)) {
-            print_error('invalidcoursemodule');
-        }
-
-        $this->context = context_module::instance($this->cm->id);
-
-        if ($course) {
-            $this->course = $course;
-        } else if ($this->cm->course == $COURSE->id) {
-            $this->course = $COURSE;
-        } else if (! $this->course = $DB->get_record('course', array('id'=>$this->cm->course))) {
-            print_error('invalidid', 'assignment');
-        }
-        $this->coursecontext = context_course::instance($this->course->id);
-        $courseshortname = format_text($this->course->shortname, true, array('context' => $this->coursecontext));
-
-        if ($assignment) {
-            $this->assignment = $assignment;
-        } else if (! $this->assignment = $DB->get_record('assignment', array('id'=>$this->cm->instance))) {
-            print_error('invalidid', 'assignment');
-        }
-
-        $this->assignment->cmidnumber = $this->cm->idnumber; // compatibility with modedit assignment obj
-        $this->assignment->courseid   = $this->course->id; // compatibility with modedit assignment obj
-
-        $this->strassignment = get_string('modulename', 'assignment');
-        $this->strassignments = get_string('modulenameplural', 'assignment');
-        $this->strsubmissions = get_string('submissions', 'assignment');
-        $this->strlastmodified = get_string('lastmodified');
-        $this->pagetitle = strip_tags($courseshortname.': '.$this->strassignment.': '.format_string($this->assignment->name, true, array('context' => $this->context)));
-
-        // visibility handled by require_login() with $cm parameter
-        // get current group only when really needed
-
-    /// Set up things for a HTML editor if it's needed
-        $this->defaultformat = editors_get_preferred_format();
-    }
-
-    /**
-     * Display the assignment, used by view.php
-     *
-     * This in turn calls the methods producing individual parts of the page
-     */
-    function view() {
-
-        $context = context_module::instance($this->cm->id);
-        require_capability('mod/assignment:view', $context);
-
-        add_to_log($this->course->id, "assignment", "view", "view.php?id={$this->cm->id}",
-                   $this->assignment->id, $this->cm->id);
-
-        $this->view_header();
-
-        $this->view_intro();
-
-        $this->view_dates();
-
-        $this->view_feedback();
-
-        $this->view_footer();
-    }
-
-    /**
-     * Display the header and top of a page
-     *
-     * (this doesn't change much for assignment types)
-     * This is used by the view() method to print the header of view.php but
-     * it can be used on other pages in which case the string to denote the
-     * page in the navigation trail should be passed as an argument
-     *
-     * @global object
-     * @param string $subpage Description of subpage to be used in navigation trail
-     */
-    function view_header($subpage='') {
-        global $CFG, $PAGE, $OUTPUT;
-
-        if ($subpage) {
-            $PAGE->navbar->add($subpage);
-        }
-
-        $PAGE->set_title($this->pagetitle);
-        $PAGE->set_heading($this->course->fullname);
-
-        echo $OUTPUT->header();
-
-        groups_print_activity_menu($this->cm, $CFG->wwwroot . '/mod/assignment/view.php?id=' . $this->cm->id);
-
-        echo '<div class="reportlink">'.$this->submittedlink().'</div>';
-        echo '<div class="clearer"></div>';
-        if (has_capability('moodle/site:config', context_system::instance())) {
-            echo $OUTPUT->notification(get_string('upgradenotification', 'assignment'));
-            $adminurl = new moodle_url('/admin/tool/assignmentupgrade/listnotupgraded.php');
-            echo $OUTPUT->single_button($adminurl, get_string('viewassignmentupgradetool', 'assignment'));
-        }
-    }
-
-
-    /**
-     * Display the assignment intro
-     *
-     * This will most likely be extended by assignment type plug-ins
-     * The default implementation prints the assignment description in a box
-     */
-    function view_intro() {
-        global $OUTPUT;
-        echo $OUTPUT->box_start('generalbox boxaligncenter', 'intro');
-        echo format_module_intro('assignment', $this->assignment, $this->cm->id);
-        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_dates() {
-        global $OUTPUT;
-        if (!$this->assignment->timeavailable && !$this->assignment->timedue) {
-            return;
-        }
-
-        echo $OUTPUT->box_start('generalbox boxaligncenter', 'dates');
-        echo '<table>';
-        if ($this->assignment->timeavailable) {
-            echo '<tr><td class="c0">'.get_string('availabledate','assignment').':</td>';
-            echo '    <td class="c1">'.userdate($this->assignment->timeavailable).'</td></tr>';
-        }
-        if ($this->assignment->timedue) {
-            echo '<tr><td class="c0">'.get_string('duedate','assignment').':</td>';
-            echo '    <td class="c1">'.userdate($this->assignment->timedue).'</td></tr>';
-        }
-        echo '</table>';
-        echo $OUTPUT->box_end();
-    }
-
-
-    /**
-     * Display the bottom and footer of a page
-     *
-     * This default method just prints the footer.
-     * This will be suitable for most assignment types
-     */
-    function view_footer() {
-        global $OUTPUT;
-        echo $OUTPUT->footer();
-    }
-
-    /**
-     * Display the feedback to the student
-     *
-     * This default method prints the teacher picture and name, date when marked,
-     * grade and teacher submissioncomment.
-     * If advanced grading is used the method render_grade from the
-     * advanced grading controller is called to display the grade.
-     *
-     * @global object
-     * @global object
-     * @global object
-     * @param object $submission The submission object or NULL in which case it will be loaded
-     * @return bool
-     */
-    function view_feedback($submission=NULL) {
-        global $USER, $CFG, $DB, $OUTPUT, $PAGE;
-        require_once($CFG->libdir.'/gradelib.php');
-        require_once("$CFG->dirroot/grade/grading/lib.php");
-
-        if (!$submission) { /// Get submission for this assignment
-            $userid = $USER->id;
-            $submission = $this->get_submission($userid);
-        } else {
-            $userid = $submission->userid;
-        }
-        // Check the user can submit
-        $canviewfeedback = ($userid == $USER->id && has_capability('mod/assignment:submit', $this->context, $USER->id, false));
-        // If not then check if the user still has the view cap and has a previous submission
-        $canviewfeedback = $canviewfeedback || (!empty($submission) && $submission->userid == $USER->id && has_capability('mod/assignment:view', $this->context));
-        // Or if user can grade (is a teacher or admin)
-        $canviewfeedback = $canviewfeedback || has_capability('mod/assignment:grade', $this->context);
-
-        if (!$canviewfeedback) {
-            // can not view or submit assignments -> no feedback
-            return false;
-        }
-
-        $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, $userid);
-        $item = $grading_info->items[0];
-        $grade = $item->grades[$userid];
-
-        if ($grade->hidden or $grade->grade === false) { // hidden or error
-            return false;
-        }
-
-        if ($grade->grade === null and empty($grade->str_feedback)) { // No grade to show yet
-            // If sumbission then check if feedback is avaiable to show else return.
-            if (!$submission) {
-                return false;
-            }
-
-            $fs = get_file_storage();
-            $noresponsefiles = $fs->is_area_empty($this->context->id, 'mod_assignment', 'response', $submission->id);
-            if (empty($submission->submissioncomment) && $noresponsefiles) { // Nothing to show yet
-                return false;
-            }
-
-            // We need the teacher info
-            if (!$teacher = $DB->get_record('user', array('id'=>$submission->teacher))) {
-                print_error('cannotfindteacher');
-            }
-
-            $feedbackdate = $submission->timemarked;
-            $feedback = format_text($submission->submissioncomment, $submission->format);
-            $strlonggrade = '-';
-        }
-        else {
-            // We need the teacher info
-            if (!$teacher = $DB->get_record('user', array('id'=>$grade->usermodified))) {
-                print_error('cannotfindteacher');
-            }
-
-            $feedbackdate = $grade->dategraded;
-            $feedback = $grade->str_feedback;
-            $strlonggrade = $grade->str_long_grade;
-        }
-
-        // Print the feedback
-        echo $OUTPUT->heading(get_string('submissionfeedback', 'assignment'), 3);
-
-        echo '<table cellspacing="0" class="feedback">';
-
-        echo '<tr>';
-        echo '<td class="left picture">';
-        if ($teacher) {
-            echo $OUTPUT->user_picture($teacher);
-        }
-        echo '</td>';
-        echo '<td class="topic">';
-        echo '<div class="from">';
-        if ($teacher) {
-            echo '<div class="fullname">'.fullname($teacher).'</div>';
-        }
-        echo '<div class="time">'.userdate($feedbackdate).'</div>';
-        echo '</div>';
-        echo '</td>';
-        echo '</tr>';
-
-        echo '<tr>';
-        echo '<td class="left side">&nbsp;</td>';
-        echo '<td class="content">';
-
-        if ($this->assignment->grade) {
-            $gradestr = '<div class="grade">'. get_string("grade").': '.$strlonggrade. '</div>';
-            if (!empty($submission) && $controller = get_grading_manager($this->context, 'mod_assignment', 'submission')->get_active_controller()) {
-                $controller->set_grade_range(make_grades_menu($this->assignment->grade));
-                echo $controller->render_grade($PAGE, $submission->id, $item, $gradestr, has_capability('mod/assignment:grade', $this->context));
-            } else {
-                echo $gradestr;
-            }
-            echo '<div class="clearer"></div>';
-        }
-
-        echo '<div class="comment">';
-        echo $feedback;
-        echo '</div>';
-        echo '</tr>';
-        if (method_exists($this, 'view_responsefile')) {
-            $this->view_responsefile($submission);
-        }
-        echo '</table>';
-
-        return true;
-    }
-
-    /**
-     * Returns a link with info about the state of the assignment submissions
-     *
-     * This is used by view_header to put this link at the top right of the page.
-     * For teachers it gives the number of submitted assignments with a link
-     * For students it gives the time of their submission.
-     * This will be suitable for most assignment types.
-     *
-     * @global object
-     * @global object
-     * @param bool $allgroup print all groups info if user can access all groups, suitable for index.php
-     * @return string
-     */
-    function submittedlink($allgroups=false) {
-        global $USER;
-        global $CFG;
-
-        $submitted = '';
-        $urlbase = "{$CFG->wwwroot}/mod/assignment/";
-
-        $context = context_module::instance($this->cm->id);
-        if (has_capability('mod/assignment:grade', $context)) {
-            if ($allgroups and has_capability('moodle/site:accessallgroups', $context)) {
-                $group = 0;
-            } else {
-                $group = groups_get_activity_group($this->cm);
-            }
-            if ($this->type == 'offline') {
-                $submitted = '<a href="'.$urlbase.'submissions.php?id='.$this->cm->id.'">'.
-                             get_string('viewfeedback', 'assignment').'</a>';
-            } else if ($count = $this->count_real_submissions($group)) {
-                $submitted = '<a href="'.$urlbase.'submissions.php?id='.$this->cm->id.'">'.
-                             get_string('viewsubmissions', 'assignment', $count).'</a>';
-            } else {
-                $submitted = '<a href="'.$urlbase.'submissions.php?id='.$this->cm->id.'">'.
-                             get_string('noattempts', 'assignment').'</a>';
-            }
-        } else {
-            if (isloggedin()) {
-                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 = '<span class="early">'.userdate($submission->timemodified).'</span>';
-                        } else {
-                            $submitted = '<span class="late">'.userdate($submission->timemodified).'</span>';
-                        }
-                    }
-                }
-            }
-        }
-
-        return $submitted;
-    }
-
-    /**
-     * Returns whether the assigment supports lateness information
-     *
-     * @return bool This assignment type supports lateness (true, default) or no (false)
-     */
-    function supports_lateness() {
-        return true;
-    }
-
-    /**
-     * @todo Document this function
-     */
-    function setup_elements(&$mform) {
-
-    }
-
-    /**
-     * Any preprocessing needed for the settings form for
-     * this assignment type
-     *
-     * @param array $default_values - array to fill in with the default values
-     *      in the form 'formelement' => 'value'
-     * @param object $form - the form that is to be displayed
-     * @return none
-     */
-    function form_data_preprocessing(&$default_values, $form) {
-    }
-
-    /**
-     * Any extra validation checks needed for the settings
-     * form for this assignment type
-     *
-     * See lib/formslib.php, 'validation' function for details
-     */
-    function form_validation($data, $files) {
-        return array();
-    }
-
-    /**
-     * Create a new assignment activity
-     *
-     * Given an object containing all the necessary data,
-     * (defined by the form in mod_form.php) this function
-     * will create a new instance and return the id number
-     * of the new instance.
-     * The due data is added to the calendar
-     * This is common to all assignment types.
-     *
-     * @global object
-     * @global object
-     * @param object $assignment The data from the form on mod_form.php
-     * @return int The id of the assignment
-     */
-    function add_instance($assignment) {
-        global $COURSE, $DB;
-
-        $assignment->timemodified = time();
-        $assignment->courseid = $assignment->course;
-
-        $returnid = $DB->insert_record("assignment", $assignment);
-        $assignment->id = $returnid;
-
-        if ($assignment->timedue) {
-            $event = new stdClass();
-            $event->name        = $assignment->name;
-            $event->description = format_module_intro('assignment', $assignment, $assignment->coursemodule);
-            $event->courseid    = $assignment->course;
-            $event->groupid     = 0;
-            $event->userid      = 0;
-            $event->modulename  = 'assignment';
-            $event->instance    = $returnid;
-            $event->eventtype   = 'due';
-            $event->timestart   = $assignment->timedue;
-            $event->timeduration = 0;
-
-            calendar_event::create($event);
-        }
-
-        assignment_grade_item_update($assignment);
-
-        return $returnid;
-    }
-
-    /**
-     * Deletes an assignment activity
-     *
-     * Deletes all database records, files and calendar events for this assignment.
-     *
-     * @global object
-     * @global object
-     * @param object $assignment The assignment to be deleted
-     * @return boolean False indicates error
-     */
-    function delete_instance($assignment) {
-        global $CFG, $DB;
-
-        $assignment->courseid = $assignment->course;
-
-        $result = true;
-
-        // now get rid of all files
-        $fs = get_file_storage();
-        if ($cm = get_coursemodule_from_instance('assignment', $assignment->id)) {
-            $context = context_module::instance($cm->id);
-            $fs->delete_area_files($context->id);
-        }
-
-        if (! $DB->delete_records('assignment_submissions', array('assignment'=>$assignment->id))) {
-            $result = false;
-        }
-
-        if (! $DB->delete_records('event', array('modulename'=>'assignment', 'instance'=>$assignment->id))) {
-            $result = false;
-        }
-
-        if (! $DB->delete_records('assignment', array('id'=>$assignment->id))) {
-            $result = false;
-        }
-        $mod = $DB->get_field('modules','id',array('name'=>'assignment'));
-
-        assignment_grade_item_delete($assignment);
-
-        return $result;
-    }
-
-    /**
-     * Updates a new assignment activity
-     *
-     * Given an object containing all the necessary data,
-     * (defined by the form in mod_form.php) this function
-     * will update the assignment instance and return the id number
-     * The due date is updated in the calendar
-     * This is common to all assignment types.
-     *
-     * @global object
-     * @global object
-     * @param object $assignment The data from the form on mod_form.php
-     * @return bool success
-     */
-    function update_instance($assignment) {
-        global $COURSE, $DB;
-
-        $assignment->timemodified = time();
-
-        $assignment->id = $assignment->instance;
-        $assignment->courseid = $assignment->course;
-
-        $DB->update_record('assignment', $assignment);
-
-        if ($assignment->timedue) {
-            $event = new stdClass();
-
-            if ($event->id = $DB->get_field('event', 'id', array('modulename'=>'assignment', 'instance'=>$assignment->id))) {
-
-                $event->name        = $assignment->name;
-                $event->description = format_module_intro('assignment', $assignment, $assignment->coursemodule);
-                $event->timestart   = $assignment->timedue;
-
-                $calendarevent = calendar_event::load($event->id);
-                $calendarevent->update($event);
-            } else {
-                $event = new stdClass();
-                $event->name        = $assignment->name;
-                $event->description = format_module_intro('assignment', $assignment, $assignment->coursemodule);
-                $event->courseid    = $assignment->course;
-                $event->groupid     = 0;
-                $event->userid      = 0;
-                $event->modulename  = 'assignment';
-                $event->instance    = $assignment->id;
-                $event->eventtype   = 'due';
-                $event->timestart   = $assignment->timedue;
-                $event->timeduration = 0;
-
-                calendar_event::create($event);
-            }
-        } else {
-            $DB->delete_records('event', array('modulename'=>'assignment', 'instance'=>$assignment->id));
-        }
-
-        // get existing grade item
-        assignment_grade_item_update($assignment);
-
-        return true;
-    }
-
-    /**
-     * Update grade item for this submission.
-     *
-     * @param stdClass $submission The submission instance
-     */
-    function update_grade($submission) {
-        assignment_update_grades($this->assignment, $submission->userid);
-    }
-
-    /**
-     * Top-level function for handling of submissions called by submissions.php
-     *
-     * This is for handling the teacher interaction with the grading interface
-     * This should be suitable for most assignment types.
-     *
-     * @global object
-     * @param string $mode Specifies the kind of teacher interaction taking place
-     */
-    function submissions($mode) {
-        ///The main switch is changed to facilitate
-        ///1) Batch fast grading
-        ///2) Skip to the next one on the popup
-        ///3) Save and Skip to the next one on the popup
-
-        //make user global so we can use the id
-        global $USER, $OUTPUT, $DB, $PAGE;
-
-        $mailinfo = optional_param('mailinfo', null, PARAM_BOOL);
-
-        if (optional_param('next', null, PARAM_BOOL)) {
-            $mode='next';
-        }
-        if (optional_param('saveandnext', null, PARAM_BOOL)) {
-            $mode='saveandnext';
-        }
-
-        if (is_null($mailinfo)) {
-            if (optional_param('sesskey', null, PARAM_BOOL)) {
-                set_user_preference('assignment_mailinfo', 0);
-            } else {
-                $mailinfo = get_user_preferences('assignment_mailinfo', 0);
-            }
-        } else {
-            set_user_preference('assignment_mailinfo', $mailinfo);
-        }
-
-        if (!($this->validate_and_preprocess_feedback())) {
-            // form was submitted ('Save' or 'Save and next' was pressed, but validation failed)
-            $this->display_submission();
-            return;
-        }
-
-        switch ($mode) {
-            case 'grade':                         // We are in a main window grading
-                if ($submission = $this->process_feedback()) {
-                    $this->display_submissions(get_string('changessaved'));
-                } else {
-                    $this->display_submissions();
-                }
-                break;
-
-            case 'single':                        // We are in a main window displaying one submission
-                if ($submission = $this->process_feedback()) {
-                    $this->display_submissions(get_string('changessaved'));
-                } else {
-                    $this->display_submission();
-                }
-                break;
-
-            case 'all':                          // Main window, display everything
-                $this->display_submissions();
-                break;
-
-            case 'fastgrade':
-                ///do the fast grading stuff  - this process should work for all 3 subclasses
-                $grading    = false;
-                $commenting = false;
-                $col        = false;
-                if (isset($_POST['submissioncomment'])) {
-                    $col = 'submissioncomment';
-                    $commenting = true;
-                }
-                if (isset($_POST['menu'])) {
-                    $col = 'menu';
-                    $grading = true;
-                }
-                if (!$col) {
-                    //both submissioncomment and grade columns collapsed..
-                    $this->display_submissions();
-                    break;
-                }
-
-                foreach ($_POST[$col] as $id => $unusedvalue){
-
-                    $id = (int)$id; //clean parameter name
-
-                    $this->process_outcomes($id);
-
-                    if (!$submission = $this->get_submission($id)) {
-                        $submission = $this->prepare_new_submission($id);
-                        $newsubmission = true;
-                    } else {
-                        $newsubmission = false;
-                    }
-                    unset($submission->data1);  // Don't need to update this.
-                    unset($submission->data2);  // Don't need to update this.
-
-                    //for fast grade, we need to check if any changes take place
-                    $updatedb = false;
-
-                    if ($grading) {
-                        $grade = $_POST['menu'][$id];
-                        $updatedb = $updatedb || ($submission->grade != $grade);
-                        $submission->grade = $grade;
-                    } else {
-                        if (!$newsubmission) {
-                            unset($submission->grade);  // Don't need to update this.
-                        }
-                    }
-                    if ($commenting) {
-                        $commentvalue = trim($_POST['submissioncomment'][$id]);
-                        $updatedb = $updatedb || ($submission->submissioncomment != $commentvalue);
-                        $submission->submissioncomment = $commentvalue;
-                    } else {
-                        unset($submission->submissioncomment);  // Don't need to update this.
-                    }
-
-                    $submission->teacher    = $USER->id;
-                    if ($updatedb) {
-                        $submission->mailed = (int)(!$mailinfo);
-                    }
-
-                    $submission->timemarked = time();
-
-                    //if it is not an update, we don't change the last modified time etc.
-                    //this will also not write into database if no submissioncomment and grade is entered.
-
-                    if ($updatedb){
-                        if ($newsubmission) {
-                            if (!isset($submission->submissioncomment)) {
-                                $submission->submissioncomment = '';
-                            }
-                            $sid = $DB->insert_record('assignment_submissions', $submission);
-                            $submission->id = $sid;
-                        } else {
-                            $DB->update_record('assignment_submissions', $submission);
-                        }
-
-                        // trigger grade event
-                        $this->update_grade($submission);
-
-                        //add to log only if updating
-                        add_to_log($this->course->id, 'assignment', 'update grades',
-                                   'submissions.php?id='.$this->cm->id.'&user='.$submission->userid,
-                                   $submission->userid, $this->cm->id);
-                    }
-
-                }
-
-                $message = $OUTPUT->notification(get_string('changessaved'), 'notifysuccess');
-
-                $this->display_submissions($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 ($submission = $this->process_feedback()) {
-                    //print_heading(get_string('changessaved'));
-                    //$extra_javascript = $this->update_main_listing($submission);
-                }
-
-            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 submission.
-                $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);
-
-                if ($mode == 'next' || $filter !== self::FILTER_REQUIRE_GRADING) {
-                    $offset = (int)$offset+1;
-                }
-                $redirect = new moodle_url('submissions.php',
-                        array('id' => $id, 'offset' => $offset, 'userid' => $nextid,
-                        'mode' => 'single', 'filter' => $filter));
-
-                redirect($redirect);
-                break;
-
-            case 'singlenosave':
-                $this->display_submission();
-                break;
-
-            default:
-                echo "something seriously is wrong!!";
-                break;
-        }
-    }
-
-    /**
-     * Checks if grading method allows quickgrade mode. At the moment it is hardcoded
-     * that advanced grading methods do not allow quickgrade.
-     *
-     * Assignment type plugins are not allowed to override this method
-     *
-     * @return boolean
-     */
-    public final function quickgrade_mode_allowed() {
-        global $CFG;
-        require_once("$CFG->dirroot/grade/grading/lib.php");
-        if ($controller = get_grading_manager($this->context, 'mod_assignment', 'submission')->get_active_controller()) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Helper method updating the listing on the main script from popup using javascript
-     *
-     * @global object
-     * @global object
-     * @param $submission object The submission whose data is to be updated on the main page
-     */
-    function update_main_listing($submission) {
-        global $SESSION, $CFG, $OUTPUT;
-
-        $output = '';
-
-        $perpage = get_user_preferences('assignment_perpage', 10);
-
-        $quickgrade = get_user_preferences('assignment_quickgrade', 0) && $this->quickgrade_mode_allowed();
-
-        /// Run some Javascript to try and update the parent page
-        $output .= '<script type="text/javascript">'."\n<!--\n";
-        if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['submissioncomment'])) {
-            if ($quickgrade){
-                $output.= 'opener.document.getElementById("submissioncomment'.$submission->userid.'").value="'
-                .trim($submission->submissioncomment).'";'."\n";
-             } else {
-                $output.= 'opener.document.getElementById("com'.$submission->userid.
-                '").innerHTML="'.shorten_text(trim(strip_tags($submission->submissioncomment)), 15)."\";\n";
-            }
-        }
-
-        if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['grade'])) {
-            //echo optional_param('menuindex');
-            if ($quickgrade){
-                $output.= 'opener.document.getElementById("menumenu'.$submission->userid.
-                '").selectedIndex="'.optional_param('menuindex', 0, PARAM_INT).'";'."\n";
-            } else {
-                $output.= 'opener.document.getElementById("g'.$submission->userid.'").innerHTML="'.
-                $this->display_grade($submission->grade)."\";\n";
-            }
-        }
-        //need to add student's assignments in there too.
-        if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['timemodified']) &&
-            $submission->timemodified) {
-            $output.= 'opener.document.getElementById("ts'.$submission->userid.
-                 '").innerHTML="'.addslashes_js($this->print_student_answer($submission->userid)).userdate($submission->timemodified)."\";\n";
-        }
-
-        if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['timemarked']) &&
-            $submission->timemarked) {
-            $output.= 'opener.document.getElementById("tt'.$submission->userid.
-                 '").innerHTML="'.userdate($submission->timemarked)."\";\n";
-        }
-
-        if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['status'])) {
-            $output.= 'opener.document.getElementById("up'.$submission->userid.'").className="s1";';
-            $buttontext = get_string('update');
-            $url = new moodle_url('/mod/assignment/submissions.php', array(
-                    'id' => $this->cm->id,
-                    'userid' => $submission->userid,
-                    'mode' => 'single',
-                    'offset' => (optional_param('offset', '', PARAM_INT)-1)));
-            $button = $OUTPUT->action_link($url, $buttontext, new popup_action('click', $url, 'grade'.$submission->userid, array('height' => 450, 'width' => 700)), array('ttile'=>$buttontext));
-
-            $output .= 'opener.document.getElementById("up'.$submission->userid.'").innerHTML="'.addslashes_js($button).'";';
-        }
-
-        $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, $submission->userid);
-
-        if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['finalgrade'])) {
-            $output.= 'opener.document.getElementById("finalgrade_'.$submission->userid.
-            '").innerHTML="'.$grading_info->items[0]->grades[$submission->userid]->str_grade.'";'."\n";
-        }
-
-        if (!empty($CFG->enableoutcomes) and empty($SESSION->flextable['mod-assignment-submissions']->collapse['outcome'])) {
-
-            if (!empty($grading_info->outcomes)) {
-                foreach($grading_info->outcomes as $n=>$outcome) {
-                    if ($outcome->grades[$submission->userid]->locked) {
-                        continue;
-                    }
-
-                    if ($quickgrade){
-                        $output.= 'opener.document.getElementById("outcome_'.$n.'_'.$submission->userid.
-                        '").selectedIndex="'.$outcome->grades[$submission->userid]->grade.'";'."\n";
-
-                    } else {
-                        $options = make_grades_menu(-$outcome->scaleid);
-                        $options[0] = get_string('nooutcome', 'grades');
-                        $output.= 'opener.document.getElementById("outcome_'.$n.'_'.$submission->userid.'").innerHTML="'.$options[$outcome->grades[$submission->userid]->grade]."\";\n";
-                    }
-
-                }
-            }
-        }
-
-        $output .= "\n-->\n</script>";
-        return $output;
-    }
-
-    /**
-     *  Return a grade in user-friendly form, whether it's a scale or not
-     *
-     * @global object
-     * @param mixed $grade
-     * @return string User-friendly representation of grade
-     */
-    function display_grade($grade) {
-        global $DB;
-
-        static $scalegrades = array();   // Cache scales for each assignment - they might have different scales!!
-
-        if ($this->assignment->grade >= 0) {    // Normal number
-            if ($grade == -1) {
-                return '-';
-            } else {
-                return $grade.' / '.$this->assignment->grade;
-            }
-
-        } else {                                // Scale
-            if (empty($scalegrades[$this->assignment->id])) {
-                if ($scale = $DB->get_record('scale', array('id'=>-($this->assignment->grade)))) {
-                    $scalegrades[$this->assignment->id] = make_menu_from_list($scale->scale);
-                } else {
-                    return '-';
-                }
-            }
-            if (isset($scalegrades[$this->assignment->id][$grade])) {
-                return $scalegrades[$this->assignment->id][$grade];
-            }
-            return '-';
-        }
-    }
-
-    /**
-     *  Display a single submission, ready for grading on a popup window
-     *
-     * This default method prints the teacher info and submissioncomment box at the top and
-     * the student info and submission at the bottom.
-     * This method also fetches the necessary data in order to be able to
-     * provide a "Next submission" button.
-     * Calls preprocess_submission() to give assignment type plug-ins a chance
-     * to process submissions before they are graded
-     * This method gets its arguments from the page parameters userid and offset
-     *
-     * @global object
-     * @global object
-     * @param string $extra_javascript
-     */
-    function display_submission($offset=-1,$userid =-1, $display=true) {
-        global $CFG, $DB, $PAGE, $OUTPUT, $USER;
-        require_once($CFG->libdir.'/gradelib.php');
-        require_once($CFG->libdir.'/tablelib.php');
-        require_once("$CFG->dirroot/repository/lib.php");
-        require_once("$CFG->dirroot/grade/grading/lib.php");
-        if ($userid==-1) {
-            $userid = required_param('userid', PARAM_INT);
-        }
-        if ($offset==-1) {
-            $offset = required_param('offset', PARAM_INT);//offset for where to start looking for student.
-        }
-        $filter = optional_param('filter', 0, PARAM_INT);
-
-        if (!$user = $DB->get_record('user', array('id'=>$userid))) {
-            print_error('nousers');
-        }
-
-        if (!$submission = $this->get_submission($user->id)) {
-            $submission = $this->prepare_new_submission($userid);
-        }
-        if ($submission->timemodified > $submission->timemarked) {
-            $subtype = 'assignmentnew';
-        } else {
-            $subtype = 'assignmentold';
-        }
-
-        $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, array($user->id));
-        $gradingdisabled = $grading_info->items[0]->grades[$userid]->locked || $grading_info->items[0]->grades[$userid]->overridden;
-
-    /// construct SQL, using current offset to find the data of the next student
-        $course     = $this->course;
-        $assignment = $this->assignment;
-        $cm         = $this->cm;
-        $context    = context_module::instance($cm->id);
-
-        //reset filter to all for offline assignment
-        if ($assignment->assignmenttype == 'offline' && $filter == self::FILTER_SUBMITTED) {
-            $filter = self::FILTER_ALL;
-        }
-        /// Get all ppl that can submit assignments
-
-        $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_SUBMITTED) {
-            $where .= 's.timemodified > 0 AND ';
-        } else if($filter == self::FILTER_REQUIRE_GRADING) {
-            $where .= 's.timemarked < s.timemodified AND ';
-        }
-
-        if ($users) {
-            $userfields = user_picture::fields('u', array('lastaccess'));
-            $select = "SELECT $userfields,
-                              s.id AS submissionid, s.grade, s.submissioncomment,
-                              s.timemodified, s.timemarked,
-                              CASE WHEN s.timemarked > 0 AND s.timemarked >= s.timemodified THEN 1
-                                   ELSE 0 END AS status ";
-
-            $sql = 'FROM {user} u '.
-                   'LEFT JOIN {assignment_submissions} s ON u.id = s.userid
-                   AND s.assignment = '.$this->assignment->id.' '.
-                   'WHERE '.$where.'u.id IN ('.implode(',', $users).') ';
-
-            if ($sort = flexible_table::get_sort_for_table('mod-assignment-submissions')) {
-                $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 ($submission->teacher) {
-            $teacher = $DB->get_record('user', array('id'=>$submission->teacher));
-        } else {
-            global $USER;
-            $teacher = $USER;
-        }
-
-        $this->preprocess_submission($submission);
-
-        $mformdata = new stdClass();
-        $mformdata->context = $this->context;
-        $mformdata->maxbytes = $this->course->maxbytes;
-        $mformdata->courseid = $this->course->id;
-        $mformdata->teacher = $teacher;
-        $mformdata->assignment = $assignment;
-        $mformdata->submission = $submission;
-        $mformdata->lateness = $this->display_lateness($submission->timemodified);
-        $mformdata->auser = $auser;
-        $mformdata->user = $user;
-        $mformdata->offset = $offset;
-        $mformdata->userid = $userid;
-        $mformdata->cm = $this->cm;
-        $mformdata->grading_info = $grading_info;
-        $mformdata->enableoutcomes = $CFG->enableoutcomes;
-        $mformdata->grade = $this->assignment->grade;
-        $mformdata->gradingdisabled = $gradingdisabled;
-        $mformdata->nextid = $nextid;
-        $mformdata->submissioncomment= $submission->submissioncomment;
-        $mformdata->submissioncommentformat= FORMAT_HTML;
-        $mformdata->submission_content= $this->print_user_files($user->id,true);
-        $mformdata->filter = $filter;
-        $mformdata->mailinfo = get_user_preferences('assignment_mailinfo', 0);
-         if ($assignment->assignmenttype == 'upload') {
-            $mformdata->fileui_options = array('subdirs'=>1, 'maxbytes'=>$assignment->maxbytes, 'maxfiles'=>$assignment->var1, 'accepted_types'=>'*', 'return_types'=>FILE_INTERNAL);
-        } elseif ($assignment->assignmenttype == 'uploadsingle') {
-            $mformdata->fileui_options = array('subdirs'=>0, 'maxbytes'=>$CFG->userquota, 'maxfiles'=>1, 'accepted_types'=>'*', 'return_types'=>FILE_INTERNAL);
-        }
-        $advancedgradingwarning = false;
-        $gradingmanager = get_grading_manager($this->context, 'mod_assignment', 'submission');
-        if ($gradingmethod = $gradingmanager->get_active_method()) {
-            $controller = $gradingmanager->get_controller($gradingmethod);
-            if ($controller->is_form_available()) {
-                $itemid = null;
-                if (!empty($submission->id)) {
-                    $itemid = $submission->id;
-                }
-                if ($gradingdisabled && $itemid) {
-                    $mformdata->advancedgradinginstance = $controller->get_current_instance($USER->id, $itemid);
-                } else if (!$gradingdisabled) {
-                    $instanceid = optional_param('advancedgradinginstanceid', 0, PARAM_INT);
-                    $mformdata->advancedgradinginstance = $controller->get_or_create_instance($instanceid, $USER->id, $itemid);
-                }
-            } else {
-                $advancedgradingwarning = $controller->form_unavailable_notification();
-            }
-        }
-
-        $submitform = new assignment_grading_form( null, $mformdata );
-
-         if (!$display) {
-            $ret_data = new stdClass();
-            $ret_data->mform = $submitform;
-            if (isset($mformdata->fileui_options)) {
-                $ret_data->fileui_options = $mformdata->fileui_options;
-            }
-            return $ret_data;
-        }
-
-        if ($submitform->is_cancelled()) {
-            redirect('submissions.php?id='.$this->cm->id);
-        }
-
-        $submitform->set_data($mformdata);
-
-        $PAGE->set_title($this->course->fullname . ': ' .get_string('feedback', 'assignment').' - '.fullname($user, true));
-        $PAGE->set_heading($this->course->fullname);
-        $PAGE->navbar->add(get_string('submissions', 'assignment'), new moodle_url('/mod/assignment/submissions.php', array('id'=>$cm->id)));
-        $PAGE->navbar->add(fullname($user, true));
-
-        echo $OUTPUT->header();
-        echo $OUTPUT->heading(get_string('feedback', 'assignment').': '.fullname($user, true));
-
-        // display mform here...
-        if ($advancedgradingwarning) {
-            echo $OUTPUT->notification($advancedgradingwarning, 'error');
-        }
-        $submitform->display();
-
-        $customfeedback = $this->custom_feedbackform($submission, true);
-        if (!empty($customfeedback)) {
-            echo $customfeedback;
-        }
-
-        echo $OUTPUT->footer();
-    }
-
-    /**
-     *  Preprocess submission before grading
-     *
-     * Called by display_submission()
-     * The default type does nothing here.
-     *
-     * @param object $submission The submission object
-     */
-    function preprocess_submission(&$submission) {
-    }
-
-    /**
-     *  Display all the submissions ready for grading
-     *
-     * @global object
-     * @global object
-     * @global object
-     * @global object
-     * @param string $message
-     * @return bool|void
-     */
-    function display_submissions($message='') {
-        global $CFG, $DB, $USER, $DB, $OUTPUT, $PAGE;
-        require_once($CFG->libdir.'/gradelib.php');
-
-        /* 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_REQUIRE_GRADING => get_string('requiregrading', '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('assignment_perpage', $perpage);
-            set_user_preference('assignment_quickgrade', optional_param('quickgrade', 0, PARAM_BOOL));
-            set_user_preference('assignment_filter', $filter);
-        }
-
-        /* next we get perpage and quickgrade (allow quick grade) params
-         * from database
-         */
-        $perpage    = get_user_preferences('assignment_perpage', 10);
-        $quickgrade = get_user_preferences('assignment_quickgrade', 0) && $this->quickgrade_mode_allowed();
-        $filter = get_user_preferences('assignment_filter', 0);
-        $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id);
-
-        if (!empty($CFG->enableoutcomes) and !empty($grading_info->outcomes)) {
-            $uses_outcomes = true;
-        } else {
-            $uses_outcomes = false;
-        }
-
-        $page    = optional_param('page', 0, PARAM_INT);
-        $strsaveallfeedback = get_string('saveallfeedback', 'assignment');
-
-    /// Some shortcuts to make the code read better
-
-        $course     = $this->course;
-        $assignment = $this->assignment;
-        $cm         = $this->cm;
-        $hassubmission = false;
-
-        // reset filter to all for offline assignment only.
-        if ($assignment->assignmenttype == 'offline') {
-            if ($filter == self::FILTER_SUBMITTED) {
-                $filter = self::FILTER_ALL;
-            }
-        } else {
-            $filters[self::FILTER_SUBMITTED] = get_string('submitted', 'assignment');
-        }
-
-        $tabindex = 1; //tabindex for quick grading tabbing; Not working for dropdowns yet
-        add_to_log($course->id, 'assignment', 'view submission', 'submissions.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();
-
-        echo '<div class="usersubmissions">';
-
-        //hook to allow plagiarism plugins to update status/print links.
-        echo plagiarism_update_status($this->course, $this->cm);
-
-        $course_context = context_course::instance($course->id);
-        if (has_capability('gradereport/grader:view', $course_context) && has_capability('moodle/grade:viewall', $course_context)) {
-            echo '<div class="allcoursegrades"><a href="' . $CFG->wwwroot . '/grade/report/grader/index.php?id=' . $course->id . '">'
-                . get_string('seeallcoursegrades', 'grades') . '</a></div>';
-        }
-
-        if (!empty($message)) {
-            echo $message;   // display messages here if any
-        }
-
-        $context = context_module::instance($cm->id);
-
-    /// Check to see if groups are being used in this assignment
-
-        /// find out current groups mode
-        $groupmode = groups_get_activity_groupmode($cm);
-        $currentgroup = groups_get_activity_group($cm, true);
-        groups_print_activity_menu($cm, $CFG->wwwroot . '/mod/assignment/submissions.php?id=' . $this->cm->id);
-
-        /// Print quickgrade form around the table
-        if ($quickgrade) {
-            $formattrs = array();
-            $formattrs['action'] = new moodle_url('/mod/assignment/submissions.php');
-            $formattrs['id'] = 'fastg';
-            $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'=> 'fastgrade'));
-            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 s.assignment = '. $this->assignment->id;
-            $assignmentsubmission = "LEFT JOIN {assignment_submissions} s ON (u.id = s.userid) ";
-            if($filter == self::FILTER_SUBMITTED) {
-                $wherefilter .= ' AND s.timemodified > 0 ';
-            } else if($filter == self::FILTER_REQUIRE_GRADING && $assignment->assignmenttype != 'offline') {
-                $wherefilter .= ' AND s.timemarked < s.timemodified ';
-            } else { // require grading for offline assignment
-                $assignmentsubmission = "";
-                $wherefilter = "";
-            }
-
-            $sql = "SELECT u.id FROM {user} u ".
-                   "LEFT JOIN ($esql) eu ON eu.id=u.id ".
-                   $assignmentsubmission.
-                   "WHERE u.deleted = 0 AND eu.id=u.id ".
-                   $wherefilter;
-        }
-
-        $users = $DB->get_records_sql($sql, $params);
-        if (!empty($users)) {
-            if($assignment->assignmenttype == 'offline' && $filter == self::FILTER_REQUIRE_GRADING) {
-                //remove users who has submitted their assignment
-                foreach ($this->get_submissions() as $submission) {
-                    if (array_key_exists($submission->userid, $users)) {
-                        unset($users[$submission->userid]);
-                    }
-                }
-            }
-            $users = array_keys($users);
-        }
-
-        // if groupmembersonly used, remove users who are not in any group
-        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('grade', 'submissioncomment', 'timemodified', 'timemarked', 'status', 'finalgrade'));
-        if ($uses_outcomes) {
-            $tablecolumns[] = 'outcome'; // no sorting based on outcomes column
-        }
-
-        $extrafieldnames = array();
-        foreach ($extrafields as $field) {
-            $extrafieldnames[] = get_user_field_name($field);
-        }
-        $tableheaders = array_merge(
-                array('', get_string('fullnameuser')),
-                $extrafieldnames,
-                array(
-                    get_string('grade'),
-                    get_string('comment', 'assignment'),
-                    get_string('lastmodified').' ('.get_string('submission', 'assignment').')',
-                    get_string('lastmodified').' ('.get_string('grade').')',
-                    get_string('status'),
-                    get_string('finalgrade', 'grades'),
-                ));
-        if ($uses_outcomes) {
-            $tableheaders[] = get_string('outcome', 'grades');
-        }
-
-        require_once($CFG->libdir.'/tablelib.php');
-        $table = new flexible_table('mod-assignment-submissions');
-
-        $table->define_columns($tablecolumns);
-        $table->define_headers($tableheaders);
-        $table->define_baseurl($CFG->wwwroot.'/mod/assignment/submissions.php?id='.$this->cm->id.'&amp;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('grade', 'grade');
-        $table->column_class('submissioncomment', 'comment');
-        $table->column_class('timemodified', 'timemodified');
-        $table->column_class('timemarked', 'timemarked');
-        $table->column_class('status', 'status');
-        $table->column_class('finalgrade', 'finalgrade');
-        if ($uses_outcomes) {
-            $table->column_class('outcome', 'outcome');
-        }
-
-        $table->set_attribute('cellspacing', '0');
-        $table->set_attribute('id', 'attempts');
-        $table->set_attribute('class', 'submissions');
-        $table->set_attribute('width', '100%');
-
-        $table->no_sorting('finalgrade');
-        $table->no_sorting('outcome');
-        $table->text_sorting('submissioncomment');
-
-        // Start working -- this is necessary as soon as the niceties are over
-        $table->setup();
-
-        /// Construct the SQL
-        list($where, $params) = $table->get_sql_where();
-        if ($where) {
-            $where .= ' AND ';
-        }
-
-        if ($filter == self::FILTER_SUBMITTED) {
-           $where .= 's.timemodified > 0 AND ';
-        } else if($filter == self::FILTER_REQUIRE_GRADING) {
-            $where = '';
-            if ($assignment->assignmenttype != 'offline') {
-               $where .= 's.timemarked < s.timemodified AND ';
-            }
-        }
-
-        if ($sort = $table->get_sql_sort()) {
-            $sort = ' ORDER BY '.$sort;
-        }
-
-        $ufields = user_picture::fields('u', $extrafields);
-        if (!empty($users)) {
-            $select = "SELECT $ufields,
-                              s.id AS submissionid, s.grade, s.submissioncomment,
-                              s.timemodified, s.timemarked,
-                              CASE WHEN s.timemarked > 0 AND s.timemarked >= s.timemodified THEN 1
-                                   ELSE 0 END AS status ";
-
-            $sql = 'FROM {user} u '.
-                   'LEFT JOIN {assignment_submissions} s ON u.id = s.userid
-                    AND s.assignment = '.$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;
-            $strupdate = get_string('update');
-            $strgrade  = get_string('grade');
-            $strview  = get_string('view');
-            $grademenu = make_grades_menu($this->assignment->grade);
-
-            if ($ausers !== false) {
-                $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, array_keys($ausers));
-                $endposition = $offset + $perpage;
-                $currentposition = 0;
-                foreach ($ausers as $auser) {
-                    if ($currentposition == $offset && $offset < $endposition) {
-                        $rowclass = null;
-                        $final_grade = $grading_info->items[0]->grades[$auser->id];
-                        $grademax = $grading_info->items[0]->grademax;
-                        $final_grade->formatted_grade = round($final_grade->grade,2) .' / ' . round($grademax,2);
-                        $locked_overridden = 'locked';
-                        if ($final_grade->overridden) {
-                            $locked_overridden = 'overridden';
-                        }
-
-                        // TODO add here code if advanced grading grade must be reviewed => $auser->status=0
-
-                        $picture = $OUTPUT->user_picture($auser);
-
-                        if (empty($auser->submissionid)) {
-                            $auser->grade = -1; //no submission yet
-                        }
-
-                        if (!empty($auser->submissionid)) {
-                            $hassubmission = true;
-                        ///Prints student answer and student modified date
-                        ///attach file or print link to student answer, depending on the type of the assignment.
-                        ///Refer to print_student_answer in inherited classes.
-                            if ($auser->timemodified > 0) {
-                                $studentmodifiedcontent = $this->print_student_answer($auser->id)
-                                        . userdate($auser->timemodified);
-                                if ($assignment->timedue && $auser->timemodified > $assignment->timedue && $this->supports_lateness()) {
-                                    $studentmodifiedcontent .= $this->display_lateness($auser->timemodified);
-                                    $rowclass = 'late';
-                                }
-                            } else {
-                                $studentmodifiedcontent = '&nbsp;';
-                            }
-                            $studentmodified = html_writer::tag('div', $studentmodifiedcontent, array('id' => 'ts' . $auser->id));
-                        ///Print grade, dropdown or text
-                            if ($auser->timemarked > 0) {
-                                $teachermodified = '<div id="tt'.$auser->id.'">'.userdate($auser->timemarked).'</div>';
-
-                                if ($final_grade->locked or $final_grade->overridden) {
-                                    $grade = '<div id="g'.$auser->id.'" class="'. $locked_overridden .'">'.$final_grade->formatted_grade.'</div>';
-                                } else if ($quickgrade) {
-                                    $attributes = array();
-                                    $attributes['tabindex'] = $tabindex++;
-                                    $menu = html_writer::label(get_string('assignment:grade', 'assignment'), 'menumenu'. $auser->id, false, array('class' => 'accesshide'));
-                                    $menu .= html_writer::select(make_grades_menu($this->assignment->grade), 'menu['.$auser->id.']', $auser->grade, array(-1=>get_string('nograde')), $attributes);
-                                    $grade = '<div id="g'.$auser->id.'">'. $menu .'</div>';
-                                } else {
-                                    $grade = '<div id="g'.$auser->id.'">'.$this->display_grade($auser->grade).'</div>';
-                                }
-
-                            } else {
-                                $teachermodified = '<div id="tt'.$auser->id.'">&nbsp;</div>';
-                                if ($final_grade->locked or $final_grade->overridden) {
-                                    $grade = '<div id="g'.$auser->id.'" class="'. $locked_overridden .'">'.$final_grade->formatted_grade.'</div>';
-                                } else if ($quickgrade) {
-                                    $attributes = array();
-                                    $attributes['tabindex'] = $tabindex++;
-                                    $menu = html_writer::label(get_string('assignment:grade', 'assignment'), 'menumenu'. $auser->id, false, array('class' => 'accesshide'));
-                                    $menu .= html_writer::select(make_grades_menu($this->assignment->grade), 'menu['.$auser->id.']', $auser->grade, array(-1=>get_string('nograde')), $attributes);
-                                    $grade = '<div id="g'.$auser->id.'">'.$menu.'</div>';
-                                } else {
-                                    $grade = '<div id="g'.$auser->id.'">'.$this->display_grade($auser->grade).'</div>';
-                                }
-                            }
-                        ///Print Comment
-                            if ($final_grade->locked or $final_grade->overridden) {
-                                $comment = '<div id="com'.$auser->id.'">'.shorten_text(strip_tags($final_grade->str_feedback),15).'</div>';
-
-                            } else if ($quickgrade) {
-                                $comment = '<div id="com'.$auser->id.'">'
-                                         . '<textarea tabindex="'.$tabindex++.'" name="submissioncomment['.$auser->id.']" id="submissioncomment'
-                                         . $auser->id.'" rows="2" cols="20" spellcheck="true">'.($auser->submissioncomment).'</textarea></div>';
-                            } else {
-                                $comment = '<div id="com'.$auser->id.'">'.shorten_text(strip_tags($auser->submissioncomment),15).'</div>';
-                            }
-                        } else {
-                            $studentmodified = '<div id="ts'.$auser->id.'">&nbsp;</div>';
-                            $teachermodified = '<div id="tt'.$auser->id.'">&nbsp;</div>';
-                            $status          = '<div id="st'.$auser->id.'">&nbsp;</div>';
-
-                            if ($final_grade->locked or $final_grade->overridden) {
-                                $grade = '<div id="g'.$auser->id.'">'.$final_grade->formatted_grade . '</div>';
-                                $hassubmission = true;
-                            } else if ($quickgrade) {   // allow editing
-                                $attributes = array();
-                                $attributes['tabindex'] = $tabindex++;
-                                $menu = html_writer::label(get_string('assignment:grade', 'assignment'), 'menumenu'. $auser->id, false, array('class' => 'accesshide'));
-                                $menu .= html_writer::select(make_grades_menu($this->assignment->grade), 'menu['.$auser->id.']', $auser->grade, array(-1=>get_string('nograde')), $attributes);
-                                $grade = '<div id="g'.$auser->id.'">'.$menu.'</div>';
-                                $hassubmission = true;
-                            } else {
-                                $grade = '<div id="g'.$auser->id.'">-</div>';
-                            }
-
-                            if ($final_grade->locked or $final_grade->overridden) {
-                                $comment = '<div id="com'.$auser->id.'">'.$final_grade->str_feedback.'</div>';
-                            } else if ($quickgrade) {
-                                $comment = '<div id="com'.$auser->id.'">'
-                                         . '<textarea tabindex="'.$tabindex++.'" name="submissioncomment['.$auser->id.']" id="submissioncomment'
-                                         . $auser->id.'" rows="2" cols="20" spellcheck="true">'.($auser->submissioncomment).'</textarea></div>';
-                            } else {
-                                $comment = '<div id="com'.$auser->id.'">&nbsp;</div>';
-                            }
-                        }
-
-                        if (empty($auser->status)) { /// Confirm we have exclusively 0 or 1
-                            $auser->status = 0;
-                        } else {
-                            $auser->status = 1;
-                        }
-
-                        $buttontext = ($auser->status == 1) ? $strupdate : $strgrade;
-                        if ($final_grade->locked or $final_grade->overridden) {
-                            $buttontext = $strview;
-                        }
-
-                        ///No more buttons, we use popups ;-).
-                        $popup_url = '/mod/assignment/submissions.php?id='.$this->cm->id
-                                   . '&amp;userid='.$auser->id.'&amp;mode=single'.'&amp;filter='.$filter.'&amp;offset='.$offset++;
-
-                        $button = $OUTPUT->action_link($popup_url, $buttontext);
-
-                        $status  = '<div id="up'.$auser->id.'" class="s'.$auser->status.'">'.$button.'</div>';
-
-                        $finalgrade = '<span id="finalgrade_'.$auser->id.'">'.$final_grade->str_grade.'</span>';
-
-                        $outcomes = '';
-
-                        if ($uses_outcomes) {
-
-                            foreach($grading_info->outcomes as $n=>$outcome) {
-                                $outcomes .= '<div class="outcome"><label for="'. 'outcome_'.$n.'_'.$auser->id .'">'.$outcome->name.'</label>';
-                                $options = make_grades_menu(-$outcome->scaleid);
-
-                                if ($outcome->grades[$auser->id]->locked or !$quickgrade) {
-                                    $options[0] = get_string('nooutcome', 'grades');
-                                    $outcomes .= ': <span id="outcome_'.$n.'_'.$auser->id.'">'.$options[$outcome->grades[$auser->id]->grade].'</span>';
-                                } else {
-                                    $attributes = array();
-                                    $attributes['tabindex'] = $tabindex++;
-                                    $attributes['id'] = 'outcome_'.$n.'_'.$auser->id;
-                                    $outcomes .= ' '.html_writer::select($options, 'outcome_'.$n.'['.$auser->id.']', $outcome->grades[$auser->id]->grade, array(0=>get_string('nooutcome', 'grades')), $attributes);
-                                }
-                                $outcomes .= '</div>';
-                            }
-                        }
-
-                        $userlink = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $auser->id . '&amp;course=' . $course->id . '">' . fullname($auser, has_capability('moodle/site:viewfullnames', $this->context)) . '</a>';
-                        $extradata = array();
-                        foreach ($extrafields as $field) {
-                            $extradata[] = $auser->{$field};
-                        }
-                        $row = array_merge(array($picture, $userlink), $extradata,
-                                array($grade, $comment, $studentmodified, $teachermodified,
-                                $status, $finalgrade));
-                        if ($uses_outcomes) {
-                            $row[] = $outcomes;
-                        }
-                        $table->add_data($row, $rowclass);
-                    }
-                    $currentposition++;
-                }
-                if ($hassubmission && method_exists($this, 'download_submissions')) {
-                    echo html_writer::start_tag('div', array('class' => 'mod-assignment-download-link'));
-                    echo html_writer::link(new moodle_url('/mod/assignment/submissions.php', array('id' => $this->cm->id, 'download' => 'zip')), get_string('downloadall', 'assignment'));
-                    echo html_writer::end_tag('div');
-                }
-                $table->print_html();  /// Print the whole table
-            } else {
-                if ($filter == self::FILTER_SUBMITTED) {
-                    echo html_writer::tag('div', get_string('nosubmisson', 'assignment'), array('class'=>'nosubmisson'));
-                } else if ($filter == self::FILTER_REQUIRE_GRADING) {
-                    echo html_writer::tag('div', get_string('norequiregrading', 'assignment'), array('class'=>'norequiregrading'));
-                }
-            }
-        }
-
-        /// Print quickgrade form around the table
-        if ($quickgrade && $table->started_output && !empty($users)){
-            $mailinfopref = false;
-            if (get_user_preferences('assignment_mailinfo', 1)) {
-                $mailinfopref = true;
-            }
-            $emailnotification =  html_writer::checkbox('mailinfo', 1, $mailinfopref, get_string('enablenotification','assignment'));
-
-            $emailnotification .= $OUTPUT->help_icon('enablenotification', 'assignment');
-            echo html_writer::tag('div', $emailnotification, array('class'=>'emailnotification'));
-
-            $savefeedback = html_writer::empty_tag('input', array('type'=>'submit', 'name'=>'fastg', 'value'=>get_string('saveallfeedback', 'assignment')));
-            echo html_writer::tag('div', $savefeedback, array('class'=>'fastgbutton'));
-
-            echo html_writer::end_tag('form');
-        } else if ($quickgrade) {
-            echo html_writer::end_tag('form');
-        }
-
-        echo '</div>';
-        /// End of fast grading form
-
-        /// Mini form for setting user preference
-
-        $formaction = new moodle_url('/mod/assignment/submissions.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', 'qgprefs', get_string('optionalsettings', 'assignment'));
-        $mform->addElement('select', 'filter', get_string('show'),  $filters);
-
-        $mform->setDefault('filter', $filter);
-
-        $mform->addElement('text', 'perpage', get_string('pagesize', 'assignment'), array('size'=>1));
-        $mform->setDefault('perpage', $perpage);
-
-        if ($this->quickgrade_mode_allowed()) {
-            $mform->addElement('checkbox', 'quickgrade', get_string('quickgrade','assignment'));
-            $mform->setDefault('quickgrade', $quickgrade);
-            $mform->addHelpButton('quickgrade', 'quickgrade', 'assignment');
-        }
-
-        $mform->addElement('submit', 'savepreferences', get_string('savepreferences'));
-
-        $mform->display();
-
-        echo $OUTPUT->footer();
-    }
-
-    /**
-     * If the form was cancelled ('Cancel' or 'Next' was pressed), call cancel method
-     * from advanced grading (if applicable) and returns true
-     * If the form was submitted, validates it and returns false if validation did not pass.
-     * If validation passes, preprocess advanced grading (if applicable) and returns true.
-     *
-     * Note to the developers: This is NOT the correct way to implement advanced grading
-     * in grading form. The assignment grading was written long time ago and unfortunately
-     * does not fully use the mforms. Usually function is_validated() is called to
-     * validate the form and get_data() is called to get the data from the form.
-     *
-     * Here we have to push the calculated grade to $_POST['xgrade'] because further processing
-     * of the form gets the data not from form->get_data(), but from $_POST (using statement
-     * like  $feedback = data_submitted() )
-     */
-    protected function validate_and_preprocess_feedback() {
-        global $USER, $CFG;
-        require_once($CFG->libdir.'/gradelib.php');
-        if (!($feedback = data_submitted()) || !isset($feedback->userid) || !isset($feedback->offset)) {
-            return true;      // No incoming data, nothing to validate
-        }
-        $userid = required_param('userid', PARAM_INT);
-        $offset = required_param('offset', PARAM_INT);
-        $gradinginfo = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, array($userid));
-        $gradingdisabled = $gradinginfo->items[0]->grades[$userid]->locked || $gradinginfo->items[0]->grades[$userid]->overridden;
-        if ($gradingdisabled) {
-            return true;
-        }
-        $submissiondata = $this->display_submission($offset, $userid, false);
-        $mform = $submissiondata->mform;
-        $gradinginstance = $mform->use_advanced_grading();
-        if (optional_param('cancel', false, PARAM_BOOL) || optional_param('next', false, PARAM_BOOL)) {
-            // form was cancelled
-            if ($gradinginstance) {
-                $gradinginstance->cancel();
-            }
-        } else if ($mform->is_submitted()) {
-            // form was submitted (= a submit button other than 'cancel' or 'next' has been clicked)
-            if (!$mform->is_validated()) {
-                return false;
-            }
-            // preprocess advanced grading here
-            if ($gradinginstance) {
-                $data = $mform->get_data();
-                // create submission if it did not exist yet because we need submission->id for storing the grading instance
-                $submission = $this->get_submission($userid, true);
-                $_POST['xgrade'] = $gradinginstance->submit_and_get_grade($data->advancedgrading, $submission->id);
-            }
-        }
-        return true;
-    }
-
-    /**
-     *  Process teacher feedback submission
-     *
-     * This is called by submissions() when a grading even has taken place.
-     * It gets its data from the submitted form.
-     *
-     * @global object
-     * @global object
-     * @global object
-     * @return object|bool The updated submission object or false
-     */
-    function process_feedback($formdata=null) {
-        global $CFG, $USER, $DB;
-        require_once($CFG->libdir.'/gradelib.php');
-
-        if (!$feedback = data_submitted() or !confirm_sesskey()) {      // No incoming data?
-            return false;
-        }
-
-        ///For save and next, we need to know the userid to save, and the userid to go
-        ///We use a new hidden field in the form, and set it to -1. If it's set, we use this
-        ///as the userid to store
-        if ((int)$feedback->saveuserid !== -1){
-            $feedback->userid = $feedback->saveuserid;
-        }
-
-        if (!empty($feedback->cancel)) {          // User hit cancel button
-            return false;
-        }
-
-        $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, $feedback->userid);
-
-        // store outcomes if needed
-        $this->process_outcomes($feedback->userid);
-
-        $submission = $this->get_submission($feedback->userid, true);  // Get or make one
-
-        if (!($grading_info->items[0]->grades[$feedback->userid]->locked ||
-            $grading_info->items[0]->grades[$feedback->userid]->overridden) ) {
-
-            $submission->grade      = $feedback->xgrade;
-            $submission->submissioncomment    = $feedback->submissioncomment_editor['text'];
-            $submission->teacher    = $USER->id;
-            $mailinfo = get_user_preferences('assignment_mailinfo', 0);
-            if (!$mailinfo) {
-                $submission->mailed = 1;       // treat as already mailed
-            } else {
-                $submission->mailed = 0;       // Make sure mail goes out (again, even)
-            }
-            $submission->timemarked = time();
-
-            unset($submission->data1);  // Don't need to update this.
-            unset($submission->data2);  // Don't need to update this.
-
-            if (empty($submission->timemodified)) {   // eg for offline assignments
-                // $submission->timemodified = time();
-            }
-
-            $DB->update_record('assignment_submissions', $submission);
-
-            // triger grade event
-            $this->update_grade($submission);
-
-            add_to_log($this->course->id, 'assignment', 'update grades',
-                       'submissions.php?id='.$this->cm->id.'&user='.$feedback->userid, $feedback->userid, $this->cm->id);
-             if (!is_null($formdata)) {
-                    if ($this->type == 'upload' || $this->type == 'uploadsingle') {
-                        $mformdata = $formdata->mform->get_data();
-                        $mformdata = file_postupdate_standard_filemanager($mformdata, 'files', $formdata->fileui_options, $this->context, 'mod_assignment', 'response', $submission->id);
-                    }
-             }
-        }
-
-        return $submission;
-
-    }
-
-    function process_outcomes($userid) {
-        global $CFG, $USER;
-
-        if (empty($CFG->enableoutcomes)) {
-            return;
-        }
-
-        require_once($CFG->libdir.'/gradelib.php');
-
-        if (!$formdata = data_submitted() or !confirm_sesskey()) {
-            return;
-        }
-
-        $data = array();
-        $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, $userid);
-
-        if (!empty($grading_info->outcomes)) {
-            foreach($grading_info->outcomes as $n=>$old) {
-                $name = 'outcome_'.$n;
-                if (isset($formdata->{$name}[$userid]) and $old->grades[$userid]->grade != $formdata->{$name}[$userid]) {
-                    $data[$n] = $formdata->{$name}[$userid];
-                }
-            }
-        }
-        if (count($data) > 0) {
-            grade_update_outcomes('mod/assignment', $this->course->id, 'mod', 'assignment', $this->assignment->id, $userid, $data);
-        }
-
-    }
-
-    /**
-     * Load the submission object for a particular user
-     *
-     * @global object
-     * @global object
-     * @param int $userid int The id of the user whose submission we want or 0 in which case USER->id is used
-     * @param bool $createnew boolean optional Defaults to false. If set to true a new submission object will be created in the database
-     * @param bool $teachermodified student submission set if false
-     * @return object|bool The submission or false (if $createnew is false and there is no existing submission).
-     */
-    function get_submission($userid=0, $createnew=false, $teachermodified=false) {
-        global $USER, $DB;
-
-        if (empty($userid)) {
-            $userid = $USER->id;
-        }
-
-        $submission = $DB->get_record('assignment_submissions', array('assignment'=>$this->assignment->id, 'userid'=>$userid));
-
-        if ($submission) {
-            return $submission;
-        } else if (!$createnew) {
-            return false;
-        }
-        $newsubmission = $this->prepare_new_submission($userid, $teachermodified);
-        $DB->insert_record("assignment_submissions", $newsubmission);
-
-        return $DB->get_record('assignment_submissions', array('assignment'=>$this->assignment->id, 'userid'=>$userid));
-    }
-
-    /**
-     * Check the given submission is complete. Preliminary rows are often created in the assignment_submissions
-     * table before a submission actually takes place. This function checks to see if the given submission has actually
-     * been submitted.
-     *
-     * @param  stdClass $submission The submission we want to check for completion
-     * @return bool                 Indicates if the submission was found to be complete
-     */
-    public function is_submitted_with_required_data($submission) {
-        return $submission->timemodified;
-    }
-
-    /**
-     * Instantiates a new submission 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 submission object
-     * @param bool $teachermodified student submission set if false
-     * @return object The submission
-     */
-    function prepare_new_submission($userid, $teachermodified=false) {
-        $submission = new stdClass();
-        $submission->assignment   = $this->assignment->id;
-        $submission->userid       = $userid;
-        $submission->timecreated = time();
-        // teachers should not be modifying modified date, except offline assignments
-        if ($teachermodified) {
-            $submission->timemodified = 0;
-        } else {
-            $submission->timemodified = $submission->timecreated;
-        }
-        $submission->numfiles     = 0;
-        $submission->data1        = '';
-        $submission->data2        = '';
-        $submission->grade        = -1;
-        $submission->submissioncomment      = '';
-        $submission->format       = 0;
-        $submission->teacher      = 0;
-        $submission->timemarked   = 0;
-        $submission->mailed       = 0;
-        return $submission;
-    }
-
-    /**
-     * Return all assignment submissions by ENROLLED students (even empty)
-     *
-     * @param string $sort optional field names for the ORDER BY in the sql query
-     * @param string $dir optional specifying the sort direction, defaults to DESC
-     * @return array The submission objects indexed by id
-     */
-    function get_submissions($sort='', $dir='DESC') {
-        return assignment_get_all_submissions($this->assignment, $sort, $dir);
-    }
-
-    /**
-     * Counts all complete (real) assignment submissions by enrolled students
-     *
-     * @param  int $groupid (optional) If nonzero then count is restricted to this group
-     * @return int          The number of submissions
-     */
-    function count_real_submissions($groupid=0) {
-        global $CFG;
-        global $DB;
-
-        // Grab the context assocated with our course module
-        $context = context_module::instance($this->cm->id);
-
-        // Get ids of users enrolled in the given course.
-        list($enroledsql, $params) = get_enrolled_sql($context, 'mod/assignment:submit', $groupid);
-        $params['assignmentid'] = $this->cm->instance;
-
-        // Get ids of users enrolled in the given course.
-        return $DB->count_records_sql("SELECT COUNT('x')
-                                         FROM {assignment_submissions} s
-                                    LEFT JOIN {assignment} a ON a.id = s.assignment
-                                   INNER JOIN ($enroledsql) u ON u.id = s.userid
-                                        WHERE s.assignment = :assignmentid AND
-                                              s.timemodified > 0", $params);
-    }
-
-    /**
-     * Alerts teachers by email of new or changed assignments that need grading
-     *
-     * First checks whether the option to email teachers is set for this assignment.
-     * Sends an email to ALL teachers in the course (or in the group if using separate groups).
-     * Uses the methods email_teachers_text() and email_teachers_html() to construct the content.
-     *
-     * @global object
-     * @global object
-     * @param $submission object The submission that has changed
-     * @return void
-     */
-    function email_teachers($submission) {
-        global $CFG, $DB;
-
-        if (empty($this->assignment->emailteachers)) {          // No need to do anything
-            return;
-        }
-
-        $user = $DB->get_record('user', array('id'=>$submission->userid));
-
-        if ($teachers = $this->get_graders($user)) {
-
-            $strassignments = get_string('modulenameplural', 'assignment');
-            $strassignment  = get_string('modulename', 'assignment');
-            $strsubmitted  = get_string('submitted', 'assignment');
-
-            foreach ($teachers as $teacher) {
-                $info = new stdClass();
-                $info->username = fullname($user, true);
-                $info->assignment = format_string($this->assignment->name,true);
-                $info->url = $CFG->wwwroot.'/mod/assignment/submissions.php?id='.$this->cm->id;
-                $info->timeupdated = userdate($submission->timemodified, '%c', $teacher->timezone);
-
-                $postsubject = $strsubmitted.': '.$info->username.' -> '.$this->assignment->name;
-                $posttext = $this->email_teachers_text($info);
-                $posthtml = ($teacher->mailformat == 1) ? $this->email_teachers_html($info) : '';
-
-                $eventdata = new stdClass();
-                $eventdata->modulename       = 'assignment';
-                $eventdata->userfrom         = $user;
-                $eventdata->userto           = $teacher;
-                $eventdata->subject          = $postsubject;
-                $eventdata->fullmessage      = $posttext;
-                $eventdata->fullmessageformat = FORMAT_PLAIN;
-                $eventdata->fullmessagehtml  = $posthtml;
-                $eventdata->smallmessage     = $postsubject;
-
-                $eventdata->name            = 'assignment_updates';
-                $eventdata->component       = 'mod_assignment';
-                $eventdata->notification    = 1;
-                $eventdata->contexturl      = $info->url;
-                $eventdata->contexturlname  = $info->assignment;
-
-                message_send($eventdata);
-            }
-        }
-    }
-
-    /**
-     * Sends a file
-     *
-     * @param string $filearea
-     * @param array $args
-     * @param bool $forcedownload whether or not force download
-     * @param array $options additional options affecting the file serving
-     * @return bool
-     */
-    function send_file($filearea, $args, $forcedownload, array $options=array()) {
-        debugging('plugin does not implement file sending', DEBUG_DEVELOPER);
-        return false;
-    }
-
-    /**
-     * Returns a list of teachers that should be grading given submission
-     *
-     * @param object $user
-     * @return array
-     */
-    function get_graders($user) {
-        global $DB;
-
-        //potential graders
-        list($enrolledsql, $params) = get_enrolled_sql($this->context, 'mod/assignment:grade', 0, true);
-        $sql = "SELECT u.*
-                  FROM {user} u
-                  JOIN ($enrolledsql) je ON je.id = u.id";
-        $potgraders = $DB->get_records_sql($sql, $params);
-
-        $graders = array();
-        if (groups_get_activity_groupmode($this->cm) == SEPARATEGROUPS) {   // Separate groups are being used
-            if ($groups = groups_get_all_groups($this->course->id, $user->id)) {  // Try to find all groups
-                foreach ($groups as $group) {
-                    foreach ($potgraders as $t) {
-                        if ($t->id == $user->id) {
-                            continue; // do not send self
-                        }
-                        if (groups_is_member($group->id, $t->id)) {
-                            $graders[$t->id] = $t;
-                        }
-                    }
-                }
-            } else {
-                // user not in group, try to find graders without group
-                foreach ($potgraders as $t) {
-                    if ($t->id == $user->id) {
-                        continue; // do not send self
-                    }
-                    if (!groups_get_all_groups($this->course->id, $t->id)) { //ugly hack
-                        $graders[$t->id] = $t;
-                    }
-                }
-            }
-        } else {
-            foreach ($potgraders as $t) {
-                if ($t->id == $user->id) {
-                    continue; // do not send self
-                }
-                $graders[$t->id] = $t;
-            }
-        }
-        return $graders;
-    }
-
-    /**
-     * Creates the text content for emails to teachers
-     *
-     * @param $info object The info used by the 'emailteachermail' language string
-     * @return string
-     */
-    function email_teachers_text($info) {
-        $posttext  = format_string($this->course->shortname, true, array('context' => $this->coursecontext)).' -> '.
-                     $this->strassignments.' -> '.
-                     format_string($this->assignment->name, true, array('context' => $this->context))."\n";
-        $posttext .= '---------------------------------------------------------------------'."\n";
-        $posttext .= get_string("emailteachermail", "assignment", $info)."\n";
-        $posttext .= "\n---------------------------------------------------------------------\n";
-        return $posttext;
-    }
-
-     /**
-     * Creates the html content for emails to teachers
-     *
-     * @param $info object The info used by the 'emailteachermailhtml' language string
-     * @return string
-     */
-    function email_teachers_html($info) {
-        global $CFG;
-        $posthtml  = '<p><font face="sans-serif">'.
-                     '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$this->course->id.'">'.format_string($this->course->shortname, true, array('context' => $this->coursecontext)).'</a> ->'.
-                     '<a href="'.$CFG->wwwroot.'/mod/assignment/index.php?id='.$this->course->id.'">'.$this->strassignments.'</a> ->'.
-                     '<a href="'.$CFG->wwwroot.'/mod/assignment/view.php?id='.$this->cm->id.'">'.format_string($this->assignment->name, true, array('context' => $this->context)).'</a></font></p>';
-        $posthtml .= '<hr /><font face="sans-serif">';
-        $posthtml .= '<p>'.get_string('emailteachermailhtml', 'assignment', $info).'</p>';
-        $posthtml .= '</font><hr />';
-        return $posthtml;
-    }
-
-    /**
-     * Produces a list of links to the files uploaded by a user
-     *
-     * @param $userid int optional id of the user. If 0 then $USER->id is used.
-     * @param $return boolean optional defaults to false. If true the list is returned rather than printed
-     * @return string optional
-     */
-    function print_user_files($userid=0, $return=false) {
-        global $CFG, $USER, $OUTPUT;
-
-        if (!$userid) {
-            if (!isloggedin()) {
-                return '';
-            }
-            $userid = $USER->id;
-        }
-
-        $output = '';
-
-        $submission = $this->get_submission($userid);
-        if (!$submission) {
-            return $output;
-        }
-
-        $fs = get_file_storage();
-        $files = $fs->get_area_files($this->context->id, 'mod_assignment', 'submission', $submission->id, "timemodified", false);
-        if (!empty($files)) {
-            require_once($CFG->dirroot . '/mod/assignment/locallib.php');
-            if ($CFG->enableportfolios) {
-                require_once($CFG->libdir.'/portfoliolib.php');
-                $button = new portfolio_add_button();
-            }
-            foreach ($files as $file) {
-                $filename = $file->get_filename();
-                $mimetype = $file->get_mimetype();
-                $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$this->context->id.'/mod_assignment/submission/'.$submission->id.'/'.$filename);
-                $output .= '<a href="'.$path.'" >'.$OUTPUT->pix_icon(file_file_icon($file), get_mimetype_description($file), 'moodle', array('class' => 'icon')).s($filename).'</a>';
-                if ($CFG->enableportfolios && $this->portfolio_exportable() && has_capability('mod/assignment:exportownsubmission', $this->context)) {
-                    $button->set_callback_options('assignment_portfolio_caller',
-                                                  array('id' => $this->cm->id, 'submissionid' => $submission->id, 'fileid' => $file->get_id()),
-                                                  'mod_assignment');
-                    $button->set_format_by_file($file);
-                    $output .= $button->to_html(PORTFOLIO_ADD_ICON_LINK);
-                }
-
-                if ($CFG->enableplagiarism) {
-                    require_once($CFG->libdir.'/plagiarismlib.php');
-                    $output .= plagiarism_get_links(array('userid'=>$userid, 'file'=>$file, 'cmid'=>$this->cm->id, 'course'=>$this->course, 'assignment'=>$this->assignment));
-                    $output .= '<br />';
-                }
-            }
-            if ($CFG->enableportfolios && count($files) > 1  && $this->portfolio_exportable() && has_capability('mod/assignment:exportownsubmission', $this->context)) {
-                $button->set_callback_options('assignment_portfolio_caller',
-                                              array('id' => $this->cm->id, 'submissionid' => $submission->id),
-                                              'mod_assignment');
-                $output .= '<br />'  . $button->to_html(PORTFOLIO_ADD_TEXT_LINK);
-            }
-        }
-
-        $output = '<div class="files">'.$output.'</div>';
-
-        if ($return) {
-            return $output;
-        }
-        echo $output;
-    }
-
-    /**
-     * Count the files uploaded by a given user
-     *
-     * @param $itemid int The submission's id as the file's itemid.
-     * @return int
-     */
-    function count_user_files($itemid) {
-        $fs = get_file_storage();
-        $files = $fs->get_area_files($this->context->id, 'mod_assignment', 'submission', $itemid, "id", false);
-        return count($files);
-    }
-
-    /**
-     * Returns true if the student is allowed to submit
-     *
-     * Checks that the assignment has started and, if the option to prevent late
-     * submissions is set, also checks that the assignment has not yet closed.
-     * @return boolean
-     */
-    function isopen() {
-        $time = time();
-        if ($this->assignment->preventlate && $this->assignment->timedue) {
-            return ($this->assignment->timeavailable <= $time && $time <= $this->assignment->timedue);
-        } else {
-            return ($this->assignment->timeavailable <= $time);
-        }
-    }
-
-
-    /**
-     * Return true if is set description is hidden till available date
-     *
-     * This is needed by calendar so that hidden descriptions do not
-     * come up in upcoming events.
-     *
-     * Check that description is hidden till available date
-     * By default return false
-     * Assignments types should implement this method if needed
-     * @return boolen
-     */
-    function description_is_hidden() {
-        return false;
-    }
-
-    /**
-     * Return an outline of the user's interaction with the assignment
-     *
-     * The default method prints the grade and timemodified
-     * @param $grade object
-     * @return object with properties ->info and ->time
-     */
-    function user_outline($grade) {
-
-        $result = new stdClass();
-        $result->info = get_string('grade').': '.$grade->str_long_grade;
-        $result->time = $grade->dategraded;
-        return $result;
-    }
-
-    /**
-     * Print complete information about the user's interaction with the assignment
-     *
-     * @param $user object
-     */
-    function user_complete($user, $grade=null) {
-        global $OUTPUT;
-
-        if ($submission = $this->get_submission($user->id)) {
-
-            $fs = get_file_storage();
-
-            if ($files = $fs->get_area_files($this->context->id, 'mod_assignment', 'submission', $submission->id, "timemodified", false)) {
-                $countfiles = count($files)." ".get_string("uploadedfiles", "assignment");
-                foreach ($files as $file) {
-                    $countfiles .= "; ".$file->get_filename();
-                }
-            }
-
-            echo $OUTPUT->box_start();
-            echo get_string("lastmodified").": ";
-            echo userdate($submission->timemodified);
-            echo $this->display_lateness($submission->timemodified);
-
-            $this->print_user_files($user->id);
-
-            echo '<br />';
-
-            $this->view_feedback($submission);
-
-            echo $OUTPUT->box_end();
-
-        } else {
-            if ($grade) {
-                echo $OUTPUT->container(get_string('grade').': '.$grade->str_long_grade);
-                if ($grade->str_feedback) {
-                    echo $OUTPUT->container(get_string('feedback').': '.$grade->str_feedback);
-                }
-            }
-            print_string("notsubmittedyet", "assignment");
-        }
-    }
-
-    /**
-     * Return a string indicating how late a submission is
-     *
-     * @param $timesubmitted int
-     * @return string
-     */
-    function display_lateness($timesubmitted) {
-        return assignment_display_lateness($timesubmitted, $this->assignment->timedue);
-    }
-
-    /**
-     * Empty method stub for all delete actions.
-     */
-    function delete() {
-        //nothing by default
-        redirect('view.php?id='.$this->cm->id);
-    }
-
-    /**
-     * Empty custom feedback grading form.
-     */
-    function custom_feedbackform($submission, $return=false) {
-        //nothing by default
-        return '';
-    }
-
-    /**
-     * Add a get_coursemodule_info function in case any assignment type wants to add 'extra' information
-     * for the course (see resource).
-     *
-     * Given a course_module object, this function returns any "extra" information that may be needed
-     * when printing this activity in a course listing.  See get_array_of_activities() in course/lib.php.
-     *
-     * @param $coursemodule object The coursemodule object (record).
-     * @return cached_cm_info Object used to customise appearance on course page
-     */
-    function get_coursemodule_info($coursemodule) {
-        return null;
-    }
-
-    /**
-     * Plugin cron method - do not use $this here, create new assignment instances if needed.
-     * @return void
-     */
-    function cron() {
-        //no plugin cron by default - override if needed
-    }
-
-    /**
-     * Reset all submissions
-     */
-    function reset_userdata($data) {
-        global $CFG, $DB;
-
-        if (!$DB->count_records('assignment', array('course'=>$data->courseid, 'assignmenttype'=>$this->type))) {
-            return array(); // no assignments of this type present
-        }
-
-        $componentstr = get_string('modulenameplural', 'assignment');
-        $status = array();
-
-        $typestr = get_string('type'.$this->type, 'assignment');
-        // ugly hack to support pluggable assignment type titles...
-        if($typestr === '[[type'.$this->type.']]'){
-            $typestr = get_string('type'.$this->type, 'assignment_'.$this->type);
-        }
-
-        if (!empty($data->reset_assignment_submissions)) {
-            $assignmentssql = "SELECT a.id
-                                 FROM {assignment} a
-                                WHERE a.course=? AND a.assignmenttype=?";
-            $params = array($data->courseid, $this->type);
-
-            // now get rid of all submissions and responses
-            $fs = get_file_storage();
-            if ($assignments = $DB->get_records_sql($assignmentssql, $params)) {
-                foreach ($assignments as $assignmentid=>$unused) {
-                    if (!$cm = get_coursemodule_from_instance('assignment', $assignmentid)) {
-                        continue;
-                    }
-                    $context = context_module::instance($cm->id);
-                    $fs->delete_area_files($context->id, 'mod_assignment', 'submission');
-                    $fs->delete_area_files($context->id, 'mod_assignment', 'response');
-                }
-            }
-
-            $DB->delete_records_select('assignment_submissions', "assignment IN ($assignmentssql)", $params);
-
-            $status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallsubmissions','assignment').': '.$typestr, 'error'=>false);
-
-            if (empty($data->reset_gradebook_grades)) {
-                // remove all grades from gradebook
-                assignment_reset_gradebook($data->courseid, $this->type);
-            }
-        }
-
-        return $status;
-    }
-
-
-    function portfolio_exportable() {
-        return false;
-    }
-
-    /**
-     * base implementation for backing up subtype specific information
-     * for one single module
-     *
-     * @param filehandle $bf file handle for xml file to write to
-     * @param mixed $preferences the complete backup preference object
-     *
-     * @return boolean
-     *
-     * @static
-     */
-    static function backup_one_mod($bf, $preferences, $assignment) {
-        return true;
-    }
-
-    /**
-     * base implementation for backing up subtype specific information
-     * for one single submission
-     *
-     * @param filehandle $bf file handle for xml file to write to
-     * @param mixed $preferences the complete backup preference object
-     * @param object $submission the assignment submission db record
-     *
-     * @return boolean
-     *
-     * @static
-     */
-    static function backup_one_submission($bf, $preferences, $assignment, $submission) {
-        return true;
-    }
-
-    /**
-     * base implementation for restoring subtype specific information
-     * for one single module
-     *
-     * @param array  $info the array representing the xml
-     * @param object $restore the restore preferences
-     *
-     * @return boolean
-     *
-     * @static
-     */
-    static function restore_one_mod($info, $restore, $assignment) {
-        return true;
-    }
-
-    /**
-     * base implementation for restoring subtype specific information
-     * for one single submission
-     *
-     * @param object $submission the newly created submission
-     * @param array  $info the array representing the xml
-     * @param object $restore the restore preferences
-     *
-     * @return boolean
-     *
-     * @static
-     */
-    static function restore_one_submission($info, $restore, $assignment, $submission) {
-        return true;
-    }
-
-} ////// End of the assignment_base class
-
-
-class assignment_grading_form extends moodleform {
-    /** @var stores the advaned grading instance (if used in grading) */
-    private $advancegradinginstance;
-
-    function definition() {
-        global $OUTPUT;
-        $mform =& $this->_form;
-
-        if (isset($this->_customdata->advancedgradinginstance)) {
-            $this->use_advanced_grading($this->_customdata->advancedgradinginstance);
-        }
-
-        $formattr = $mform->getAttributes();
-        $formattr['id'] = 'submitform';
-        $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', 'grade');
-        $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) . '<br/>' .
-                                                userdate($this->_customdata->submission->timemodified) .
-                                                $this->_customdata->lateness );
-
-        $this->add_submission_content();
-        $this->add_grades_section();
-
-        $this->add_feedback_section();
-
-        if ($this->_customdata->submission->timemarked) {
-            $datestring = userdate($this->_customdata->submission->timemarked)."&nbsp; (".format_time(time() - $this->_customdata->submission->timemarked).")";
-            $mform->addElement('header', 'Last Grade', get_string('lastgrade', 'assignment'));
-            $mform->addElement('static', 'picture', $OUTPUT->user_picture($this->_customdata->teacher) ,
-                                                    fullname($this->_customdata->teacher,true).
-                                                    '<br/>'.$datestring);
-        }
-        // buttons
-        $this->add_action_buttons();
-
-    }
-
-    /**
-     * Gets or sets the instance for advanced grading
-     *
-     * @param gradingform_instance $gradinginstance
-     */
-    public function use_advanced_grading($gradinginstance = false) {
-        if ($gradinginstance !== false) {
-            $this->advancegradinginstance = $gradinginstance;
-        }
-        return $this->advancegradinginstance;
-    }
-
-    /**
-     * Add the grades configuration section to the assignment configuration form
-     */
-    function add_grades_section() {
-        global $CFG;
-        $mform =& $this->_form;
-        $attributes = array();
-        if ($this->_customdata->gradingdisabled) {
-            $attributes['disabled'] ='disabled';
-        }
-
-        $mform->addElement('header', 'Grades', get_string('grades', 'grades'));
-
-        $grademenu = make_grades_menu($this->_customdata->assignment->grade);
-        if ($gradinginstance = $this->use_advanced_grading()) {
-            $gradinginstance->get_controller()->set_grade_range($grademenu);
-            $gradingelement = $mform->addElement('grading', 'advancedgrading', get_string('grade').':', array('gradinginstance' => $gradinginstance));
-            if ($this->_customdata->gradingdisabled) {
-                $gradingelement->freeze();
-            } else {
-                $mform->addElement('hidden', 'advancedgradinginstanceid', $gradinginstance->get_id());
-            }
-        } else {
-            // use simple direct grading
-            $grademenu['-1'] = get_string('nograde');
-
-            $mform->addElement('select', 'xgrade', get_string('grade').':', $grademenu, $attributes);
-            $mform->setDefault('xgrade', $this->_customdata->submission->grade ); //@fixme some bug when element called 'grade' makes it break
-            $mform->setType('xgrade', PARAM_INT);
-        }
-
-        if (!empty($this->_customdata->enableoutcomes)) {
-            foreach($this->_customdata->grading_info->outcomes as $n=>$outcome) {
-                $options = make_grades_menu(-$outcome->scaleid);
-                if ($outcome->grades[$this->_customdata->submission->userid]->locked) {
-                    $options[0] = get_string('nooutcome', 'grades');
-                    $mform->addElement('static', 'outcome_'.$n.'['.$this->_customdata->userid.']', $outcome->name.':',
-                            $options[$outcome->grades[$this->_customdata->submission->userid]->grade]);
-                } else {
-                    $options[''] = get_string('nooutcome', 'grades');
-                    $attributes = array('id' => 'menuoutcome_'.$n );
-                    $mform->addElement('select', 'outcome_'.$n.'['.$this->_customdata->userid.']', $outcome->name.':', $options, $attributes );
-                    $mform->setType('outcome_'.$n.'['.$this->_customdata->userid.']', PARAM_INT);
-                    $mform->setDefault('outcome_'.$n.'['.$this->_customdata->userid.']', $outcome->grades[$this->_customdata->submission->userid]->grade );
-                }
-            }
-        }
-        $course_context = context_module::instance($this->_customdata->cm->id);
-        if (has_capability('gradereport/grader:view', $course_context) && has_capability('moodle/grade:viewall', $course_context)) {
-            $grade = '<a href="'.$CFG->wwwroot.'/grade/report/grader/index.php?id='. $this->_customdata->courseid .'" >'.
-                        $this->_customdata->grading_info->items[0]->grades[$this->_customdata->userid]->str_grade . '</a>';
-        }else{
-            $grade = $this->_customdata->grading_info->items[0]->grades[$this->_customdata->userid]->str_grade;
-        }
-        $mform->addElement('static', 'finalgrade', get_string('currentgrade', 'assignment').':' ,$grade);
-        $mform->setType('finalgrade', PARAM_INT);
-    }
-
-    /**
-     *
-     * @global core_renderer $OUTPUT
-     */
-    function add_feedback_section() {
-        global $OUTPUT;
-        $mform =& $this->_form;
-        $mform->addElement('header', 'Feed Back', get_string('feedback', 'grades'));
-
-        if ($this->_customdata->gradingdisabled) {
-            $mform->addElement('static', 'disabledfeedback', $this->_customdata->grading_info->items[0]->grades[$this->_customdata->userid]->str_feedback );
-        } else {
-            // visible elements
-
-            $mform->addElement('editor', 'submissioncomment_editor', get_string('feedback', 'assignment').':', null, $this->get_editor_options() );
-            $mform->setType('submissioncomment_editor', PARAM_RAW); // to be cleaned before display
-            $mform->setDefault('submissioncomment_editor', $this->_customdata->submission->submissioncomment);
-            //$mform->addRule('submissioncomment', get_string('required'), 'required', null, 'client');
-            switch ($this->_customdata->assignment->assignmenttype) {
-                case 'upload' :
-                case 'uploadsingle' :
-                    $mform->addElement('filemanager', 'files_filemanager', get_string('responsefiles', 'assignment'). ':', null, $this->_customdata->fileui_options);
-                    break;
-                default :
-                    break;
-            }
-            $mform->addElement('hidden', 'mailinfo_h', "0");
-            $mform->setType('mailinfo_h', PARAM_INT);
-            $mform->addElement('checkbox', 'mailinfo',get_string('enablenotification','assignment').
-            $OUTPUT->help_icon('enablenotification', 'assignment') .':' );
-            $mform->setType('mailinfo', PARAM_INT);
-        }
-    }
-
-    function add_action_buttons($cancel = true, $submitlabel = NULL) {
-        $mform =& $this->_form;
-        //if there are more to be graded.
-        if ($this->_customdata->nextid>0) {
-            $buttonarray=array();
-            $buttonarray[] = &$mform->createElement('submit', 'submitbutton', get_string('savechanges'));
-            //@todo: fix accessibility: javascript dependency not necessary
-            $buttonarray[] = &$mform->createElement('submit', 'saveandnext', get_string('saveandnext'));
-            $buttonarray[] = &$mform->createElement('submit', 'next', get_string('next'));
-            $buttonarray[] = &$mform->createElement('cancel');
-        } else {
-            $buttonarray=array();
-            $buttonarray[] = &$mform->createElement('submit', 'submitbutton', get_string('savechanges'));
-            $buttonarray[] = &$mform->createElement('cancel');
-        }
-        $mform->addGroup($buttonarray, 'grading_buttonar', '', array(' '), false);
-        $mform->closeHeaderBefore('grading_buttonar');
-        $mform->setType('grading_buttonar', PARAM_RAW);
-    }
-
-    function add_submission_content() {
-        $mform =& $this->_form;
-        $mform->addElement('header', 'Submission', get_string('submission', 'assignment'));
-        $mform->addElement('static', '', '' , $this->_customdata->submission_content );
-    }
-
-    protected function get_editor_options() {
-        $editoroptions = array();
-        $editoroptions['component'] = 'mod_assignment';
-        $editoroptions['filearea'] = 'feedback';
-        $editoroptions['noclean'] = false;
-        $editoroptions['maxfiles'] = 0; //TODO: no files for now, we need to first implement assignment_feedback area, integration with gradebook, files support in quickgrading, etc. (skodak)
-        $editoroptions['maxbytes'] = $this->_customdata->maxbytes;
-        $editoroptions['context'] = $this->_customdata->context;
-        return $editoroptions;
-    }
-
-    public function set_data($data) {
-        $editoroptions = $this->get_editor_options();
-        if (!isset($data->text)) {
-            $data->text = '';
-        }
-        if (!isset($data->format)) {
-            $data->textformat = FORMAT_HTML;
-        } else {
-            $data->textformat = $data->format;
-        }
-
-        if (!empty($this->_customdata->submission->id)) {
-            $itemid = $this->_customdata->submission->id;
-        } else {
-            $itemid = null;
-        }
-
-        switch ($this->_customdata->assignment->assignmenttype) {
-                case 'upload' :
-                case 'uploadsingle' :
-                    $data = file_prepare_standard_filemanager($data, 'files', $editoroptions, $this->_customdata->context, 'mod_assignment', 'response', $itemid);
-                    break;
-                default :
-                    break;
-        }
-
-        $data = file_prepare_standard_editor($data, 'submissioncomment', $editoroptions, $this->_customdata->context, $editoroptions['component'], $editoroptions['filearea'], $itemid);
-        return parent::set_data($data);
-    }
-
-    public function get_data() {
-        $data = parent::get_data();
-
-        if (!empty($this->_customdata->submission->id)) {
-            $itemid = $this->_customdata->submission->id;
-        } else {
-            $itemid = null; //TODO: this is wrong, itemid MUST be known when saving files!! (skodak)
-        }
-
-        if ($data) {
-            $editoroptions = $this->get_editor_options();
-            switch ($this->_customdata->assignment->assignmenttype) {
-                case 'upload' :
-                case 'uploadsingle' :
-                    $data = file_postupdate_standard_filemanager($data, 'files', $editoroptions, $this->_customdata->context, 'mod_assignment', 'response', $itemid);
-                    break;
-                default :
-                    break;
-            }
-            $data = file_postupdate_standard_editor($data, 'submissioncomment', $editoroptions, $this->_customdata->context, $editoroptions['component'], $editoroptions['filearea'], $itemid);
-        }
-
-        if ($this->use_advanced_grading() && !isset($data->advancedgrading)) {
-            $data->advancedgrading = null;
-        }
-
-        return $data;
-    }
-}
-
-/// OTHER STANDARD FUNCTIONS ////////////////////////////////////////////////////////
-
-/**
- * Deletes an assignment instance
- *
- * This is done by calling the delete_instance() method of the assignment type class
- */
-function assignment_delete_instance($id){
-    global $CFG, $DB;
-
-    if (! $assignment = $DB->get_record('assignment', array('id'=>$id))) {
-        return false;
-    }
-
-    // fall back to base class if plugin missing
-    $classfile = "$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php";
-    if (file_exists($classfile)) {
-        require_once($classfile);
-        $assignmentclass = "assignment_$assignment->assignmenttype";
-
-    } else {
-        debugging("Missing assignment plug-in: {$assignment->assignmenttype}. Using base class for deleting instead.");
-        $assignmentclass = "assignment_base";
-    }
-
-    $ass = new $assignmentclass();
-    return $ass->delete_instance($assignment);
-}
-
-
-/**
- * Updates an assignment instance
- *
- * This is done by calling the update_instance() method of the assignment type class
- */
-function assignment_update_instance($assignment){
-    global $CFG;
-
-    $assignment->assignmenttype = clean_param($assignment->assignmenttype, PARAM_PLUGIN);
-
-    require_once("$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php");
-    $assignmentclass = "assignment_$assignment->assignmenttype";
-    $ass = new $assignmentclass();
-    return $ass->update_instance($assignment);
-}
-
-
-/**
- * Adds an assignment instance
- *
- * This is done by calling the add_instance() method of the assignment type class
- *
- * @param stdClass $assignment
- * @param mod_assignment_mod_form $mform
- * @return int intance id
- */
-function assignment_add_instance($assignment, $mform = null) {
-    global $CFG;
-
-    $assignment->assignmenttype = clean_param($assignment->assignmenttype, PARAM_PLUGIN);
-
-    require_once("$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php");
-    $assignmentclass = "assignment_$assignment->assignmenttype";
-    $ass = new $assignmentclass();
-    return $ass->add_instance($assignment);
-}
-
-
-/**
- * Returns an outline of a user interaction with an assignment
- *
- * This is done by calling the user_outline() method of the assignment type class
- */
-function assignment_user_outline($course, $user, $mod, $assignment) {
-    global $CFG;
-
-    require_once("$CFG->libdir/gradelib.php");
-    require_once("$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php");
-    $assignmentclass = "assignment_$assignment->assignmenttype";
-    $ass = new $assignmentclass($mod->id, $assignment, $mod, $course);
-    $grades = grade_get_grades($course->id, 'mod', 'assignment', $assignment->id, $user->id);
-    if (!empty($grades->items[0]->grades)) {
-        return $ass->user_outline(reset($grades->items[0]->grades));
-    } else {
-        return null;
-    }
-}
-
-/**
- * Prints the complete info about a user's interaction with an assignment
- *
- * This is done by calling the user_complete() method of the assignment type class
- */
-function assignment_user_complete($course, $user, $mod, $assignment) {
-    global $CFG;
-
-    require_once("$CFG->libdir/gradelib.php");
-    require_once("$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php");
-    $assignmentclass = "assignment_$assignment->assignmenttype";
-    $ass = new $assignmentclass($mod->id, $assignment, $mod, $course);
-    $grades = grade_get_grades($course->id, 'mod', 'assignment', $assignment->id, $user->id);
-    if (empty($grades->items[0]->grades)) {
-        $grade = false;
-    } else {
-        $grade = reset($grades->items[0]->grades);
-    }
-    return $ass->user_complete($user, $grade);
-}
-
-/**
- * Function to be run periodically according to the moodle cron
- *
- * Finds all assignment notifications that have yet to be mailed out, and mails them
- */
-function assignment_cron () {
-    global $CFG, $USER, $DB;
-
-    /// first execute all crons in plugins
-    if ($plugins = core_component::get_plugin_list('assignment')) {
-        foreach ($plugins as $plugin=>$dir) {
-            require_once("$dir/assignment.class.php");
-            $assignmentclass = "assignment_$plugin";
-            $ass = new $assignmentclass();
-            $ass->cron();
-        }
-    }
-
-    /// Notices older than 1 day will not be mailed.  This is to avoid the problem where
-    /// cron has not been running for a long time, and then suddenly people are flooded
-    /// with mail from the past few weeks or months
-
-    $timenow   = time();
-    $endtime   = $timenow - $CFG->maxeditingtime;
-    $starttime = $endtime - 24 * 3600;   /// One day earlier
-
-    if ($submissions = assignment_get_unmailed_submissions($starttime, $endtime)) {
-
-        $realuser = clone($USER);
-
-        foreach ($submissions as $key => $submission) {
-            $DB->set_field("assignment_submissions", "mailed", "1", array("id"=>$submission->id));
-        }
-
-        $timenow = time();
-
-        foreach ($submissions as $submission) {
-
-            echo "Processing assignment submission $submission->id\n";
-
-            if (! $user = $DB->get_record("user", array("id"=>$submission->userid))) {
-                echo "Could not find user $user->id\n";
-                continue;
-            }
-
-            if (! $course = $DB->get_record("course", array("id"=>$submission->course))) {
-                echo "Could not find course $submission->course\n";
-                continue;
-            }
-
-            /// Override the language and timezone of the "current" user, so that
-            /// mail is customised for the receiver.
-            cron_setup_user($user, $course);
-
-            $coursecontext = context_course::instance($submission->course);
-            $courseshortname = format_string($course->shortname, true, array('context' => $coursecontext));
-            if (!is_enrolled($coursecontext, $user->id)) {
-                echo fullname($user)." not an active participant in " . $courseshortname . "\n";
-                continue;
-            }
-
-            if (! $teacher = $DB->get_record("user", array("id"=>$submission->teacher))) {
-                echo "Could not find teacher $submission->teacher\n";
-                continue;
-            }
-
-            if (! $mod = get_coursemodule_from_instance("assignment", $submission->assignment, $course->id)) {
-                echo "Could not find course module for assignment id $submission->assignment\n";
-                continue;
-            }
-
-            if (! $mod->visible) {    /// Hold mail notification for hidden assignments until later
-                continue;
-            }
-
-            $strassignments = get_string("modulenameplural", "assignment");
-            $strassignment  = get_string("modulename", "assignment");
-
-            $assignmentinfo = new stdClass();
-            $assignmentinfo->teacher = fullname($teacher);
-            $assignmentinfo->assignment = format_string($submission->name,true);
-            $assignmentinfo->url = "$CFG->wwwroot/mod/assignment/view.php?id=$mod->id";
-
-            $postsubject = "$courseshortname: $strassignments: ".format_string($submission->name,true);
-            $posttext  = "$courseshortname -> $strassignments -> ".format_string($submission->name,true)."\n";
-            $posttext .= "---------------------------------------------------------------------\n";
-            $posttext .= get_string("assignmentmail", "assignment", $assignmentinfo)."\n";
-            $posttext .= "---------------------------------------------------------------------\n";
-
-            if ($user->mailformat == 1) {  // HTML
-                $posthtml = "<p><font face=\"sans-serif\">".
-                "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$courseshortname</a> ->".
-                "<a href=\"$CFG->wwwroot/mod/assignment/index.php?id=$course->id\">$strassignments</a> ->".
-                "<a href=\"$CFG->wwwroot/mod/assignment/view.php?id=$mod->id\">".format_string($submission->name,true)."</a></font></p>";
-                $posthtml .= "<hr /><font face=\"sans-serif\">";
-                $posthtml .= "<p>".get_string("assignmentmailhtml", "assignment", $assignmentinfo)."</p>";
-                $posthtml .= "</font><hr />";
-            } else {
-                $posthtml = "";
-            }
-
-            $eventdata = new stdClass();
-            $eventdata->modulename       = 'assignment';
-            $eventdata->userfrom         = $teacher;
-            $eventdata->userto           = $user;
-            $eventdata->subject          = $postsubject;
-            $eventdata->fullmessage      = $posttext;
-            $eventdata->fullmessageformat = FORMAT_PLAIN;
-            $eventdata->fullmessagehtml  = $posthtml;
-            $eventdata->smallmessage     = get_string('assignmentmailsmall', 'assignment', $assignmentinfo);
-
-            $eventdata->name            = 'assignment_updates';
-            $eventdata->component       = 'mod_assignment';
-            $eventdata->notification    = 1;
-            $eventdata->contexturl      = $assignmentinfo->url;
-            $eventdata->contexturlname  = $assignmentinfo->assignment;
-
-            message_send($eventdata);
-        }
-
-        cron_setup_user();
-    }
-
-    return true;
-}
-
-/**
- * Return grade for given user or all users.
- *
- * @param stdClass $assignment An assignment instance
- * @param int $userid Optional user id, 0 means all users
- * @return array An array of grades, false if none
- */
-function assignment_get_user_grades($assignment, $userid=0) {
-    global $CFG, $DB;
-
-    if ($userid) {
-        $user = "AND u.id = :userid";
-        $params = array('userid'=>$userid);
-    } else {
-        $user = "";
-    }
-    $params['aid'] = $assignment->id;
-
-    $sql = "SELECT u.id, u.id AS userid, s.grade AS rawgrade, s.submissioncomment AS feedback, s.format AS feedbackformat,
-                   s.teacher AS usermodified, s.timemarked AS dategraded, s.timemodified AS datesubmitted
-              FROM {user} u, {assignment_submissions} s
-             WHERE u.id = s.userid AND s.assignment = :aid
-                   $user";
-
-    return $DB->get_records_sql($sql, $params);
-}
-
-/**
- * Update activity grades
- *
- * @category grade
- * @param stdClass $assignment Assignment instance
- * @param int $userid specific user only, 0 means all
- * @param bool $nullifnone Not used
- */
-function assignment_update_grades($assignment, $userid=0, $nullifnone=true) {
-    global $CFG, $DB;
-    require_once($CFG->libdir.'/gradelib.php');
-
-    if ($assignment->grade == 0) {
-        assignment_grade_item_update($assignment);
-
-    } else if ($grades = assignment_get_user_grades($assignment, $userid)) {
-        foreach($grades as $k=>$v) {
-            if ($v->rawgrade == -1) {
-                $grades[$k]->rawgrade = null;
-            }
-        }
-        assignment_grade_item_update($assignment, $grades);
-
-    } else {
-        assignment_grade_item_update($assignment);
-    }
-}
-
-/**
- * Update all grades in gradebook.
- */
-function assignment_upgrade_grades() {
-    global $DB;
-
-    $sql = "SELECT COUNT('x')
-              FROM {assignment} a, {course_modules} cm, {modules} m
-             WHERE m.name='assignment' AND m.id=cm.module AND cm.instance=a.id";
-    $count = $DB->count_records_sql($sql);
-
-    $sql = "SELECT a.*, cm.idnumber AS cmidnumber, a.course AS courseid
-              FROM {assignment} a, {course_modules} cm, {modules} m
-             WHERE m.name='assignment' AND m.id=cm.module AND cm.instance=a.id";
-    $rs = $DB->get_recordset_sql($sql);
-    if ($rs->valid()) {
-        // too much debug output
-        $pbar = new progress_bar('assignmentupgradegrades', 500, true);
-        $i=0;
-        foreach ($rs as $assignment) {
-            $i++;
-            upgrade_set_timeout(60*5); // set up timeout, may also abort execution
-            assignment_update_grades($assignment);
-            $pbar->update($i, $count, "Updating Assignment grades ($i/$count).");
-        }
-        upgrade_set_timeout(); // reset to default timeout
-    }
-    $rs->close();
-}
-
-/**
- * Create grade item for given assignment
- *
- * @category grade
- * @param stdClass $assignment An assignment instance with extra cmidnumber property
- * @param mixed $grades Optional array/object of grade(s); 'reset' means reset grades in gradebook
- * @return int 0 if ok, error code otherwise
- */
-function assignment_grade_item_update($assignment, $grades=NULL) {
-    global $CFG;
-    require_once($CFG->libdir.'/gradelib.php');
-
-    if (!isset($assignment->courseid)) {
-        $assignment->courseid = $assignment->course;
-    }
-
-    $params = array('itemname'=>$assignment->name, 'idnumber'=>$assignment->cmidnumber);
-
-    if ($assignment->grade > 0) {
-        $params['gradetype'] = GRADE_TYPE_VALUE;
-        $params['grademax']  = $assignment->grade;
-        $params['grademin']  = 0;
-
-    } else if ($assignment->grade < 0) {
-        $params['gradetype'] = GRADE_TYPE_SCALE;
-        $params['scaleid']   = -$assignment->grade;
-
-    } else {
-        $params['gradetype'] = GRADE_TYPE_TEXT; // allow text comments only
-    }
-
-    if ($grades  === 'reset') {
-        $params['reset'] = true;
-        $grades = NULL;
-    }
-
-    return grade_update('mod/assignment', $assignment->courseid, 'mod', 'assignment', $assignment->id, 0, $grades, $params);
-}
-
-/**
- * Delete grade item for given assignment
- *
- * @category grade
- * @param object $assignment object
- * @return object assignment
- */
-function assignment_grade_item_delete($assignment) {
-    global $CFG;
-    require_once($CFG->libdir.'/gradelib.php');
-
-    if (!isset($assignment->courseid)) {
-        $assignment->courseid = $assignment->course;
-    }
-
-    return grade_update('mod/assignment', $assignment->courseid, 'mod', 'assignment', $assignment->id, 0, NULL, array('deleted'=>1));
-}
-
-
-/**
- * Serves assignment submissions and other files.
- *
- * @package  mod_assignment
- * @category files
- * @param stdClass $course course object
- * @param stdClass $cm course module object
- * @param stdClass $context context object
- * @param string $filearea file area
- * @param array $args extra arguments
- * @param bool $forcedownload whether or not force download
- * @param array $options additional options affecting the file serving
- * @return bool false if file not found, does not return if found - just send the file
- */
-function assignment_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) {
-    global $CFG, $DB;
-
-    if ($context->contextlevel != CONTEXT_MODULE) {
-        return false;
-    }
-
-    require_login($course, false, $cm);
-
-    if (!$assignment = $DB->get_record('assignment', array('id'=>$cm->instance))) {
-        return false;
-    }
-
-    require_once($CFG->dirroot.'/mod/assignment/type/'.$assignment->assignmenttype.'/assignment.class.php');
-    $assignmentclass = 'assignment_'.$assignment->assignmenttype;
-    $assignmentinstance = new $assignmentclass($cm->id, $assignment, $cm, $course);
-
-    return $assignmentinstance->send_file($filearea, $args, $forcedownload, $options);
-}
-/**
- * Checks if a scale is being used by an assignment
- *
- * This is used by the backup code to decide whether to back up a scale
- * @param $assignmentid int
- * @param $scaleid int
- * @return boolean True if the scale is used by the assignment
- */
-function assignment_scale_used($assignmentid, $scaleid) {
-    global $DB;
-
-    $return = false;
-
-    $rec = $DB->get_record('assignment', array('id'=>$assignmentid,'grade'=>-$scaleid));
-
-    if (!empty($rec) && !empty($scaleid)) {
-        $return = true;
-    }
-
-    return $return;
-}
-
-/**
- * Checks if scale is being used by any instance of assignment
- *
- * This is used to find out if scale used anywhere
- * @param $scaleid int
- * @return boolean True if the scale is used by any assignment
- */
-function assignment_scale_used_anywhere($scaleid) {
-    global $DB;
-
-    if ($scaleid and $DB->record_exists('assignment', array('grade'=>-$scaleid))) {
-        return true;
-    } else {
-        return false;
-    }
-}
-
-/**
- * Make sure up-to-date events are created for all assignment instances
- *
- * This standard function will check all instances of this module
- * and make sure there are up-to-date events created for each of them.
- * If courseid = 0, then every assignment event in the site is checked, else
- * only assignment events belonging to the course specified are checked.
- * This function is used, in its new format, by restore_refresh_events()
- *
- * @param $courseid int optional If zero then all assignments for all courses are covered
- * @return boolean Always returns true
- */
-function assignment_refresh_events($courseid = 0) {
-    global $DB, $CFG;
-    require_once($CFG->dirroot.'/calendar/lib.php');
-
-    if ($courseid == 0) {
-        if (! $assignments = $DB->get_records("assignment")) {
-            return true;
-        }
-    } else {
-        if (! $assignments = $DB->get_records("assignment", array("course"=>$courseid))) {
-            return true;
-        }
-    }
-    $moduleid = $DB->get_field('modules', 'id', array('name'=>'assignment'));
-
-    foreach ($assignments as $assignment) {
-        $cm = get_coursemodule_from_instance('assignment', $assignment->id, $courseid, false, MUST_EXIST);
-        $event = new stdClass();
-        $event->name        = $assignment->name;
-        $event->description = format_module_intro('assignment', $assignment, $cm->id);
-        $event->timestart   = $assignment->timedue;
-
-        if ($event->id = $DB->get_field('event', 'id', array('modulename'=>'assignment', 'instance'=>$assignment->id))) {
-            $calendarevent = calendar_event::load($event->id);
-            $calendarevent->update($event);
-        } else {
-            $event->courseid    = $assignment->course;
-            $event->groupid     = 0;
-            $event->userid      = 0;
-            $event->modulename  = 'assignment';
-            $event->instance    = $assignment->id;
-            $event->eventtype   = 'due';
-            $event->timeduration = 0;
-            $event->visible     = $DB->get_field('course_modules', 'visible', array('module'=>$moduleid, 'instance'=>$assignment->id));
-            calendar_event::create($event);
-        }
-
-    }
-    return true;
-}
-
-/**
- * Print recent activity from all assignments in a given course
- *
- * This is used by the recent activity block
- */
-function assignment_print_recent_activity($course, $viewfullnames, $timestart) {
-    global $CFG, $USER, $DB, $OUTPUT;
-
-    // do not use log table if possible, it may be huge
-
-    if (!$submissions = $DB->get_records_sql("SELECT asb.id, asb.timemodified, cm.id AS cmid, asb.userid,
-                                                     u.firstname, u.lastname, u.email, u.picture
-                                                FROM {assignment_submissions} asb
-                                                     JOIN {assignment} a      ON a.id = asb.assignment
-                                                     JOIN {course_modules} cm ON cm.instance = a.id
-                                                     JOIN {modules} md        ON md.id = cm.module
-                                                     JOIN {user} u            ON u.id = asb.userid
-                                               WHERE asb.timemodified > ? AND
-                                                     a.course = ? AND
-                                                     md.name = 'assignment'
-                                            ORDER BY asb.timemodified ASC", array($timestart, $course->id))) {
-         return false;
-    }
-
-    $modinfo = get_fast_modinfo($course); // reference needed because we might load the groups
-    $show    = array();
-    $grader  = array();
-
-    foreach($submissions as $submission) {
-        if (!array_key_exists($submission->cmid, $modinfo->cms)) {
-            continue;
-        }
-        $cm = $modinfo->cms[$submission->cmid];
-        if (!$cm->uservisible) {
-            continue;
-        }
-        if ($submission->userid == $USER->id) {
-            $show[] = $submission;
-            continue;
-        }
-
-        // the act of sumbitting of assignment may be considered private - only graders will see it if specified
-        if (empty($CFG->assignment_showrecentsubmissions)) {
-            if (!array_key_exists($cm->id, $grader)) {
-                $grader[$cm->id] = has_capability('moodle/grade:viewall', context_module::instance($cm->id));
-            }
-            if (!$grader[$cm->id]) {
-                continue;
-            }
-        }
-
-        $groupmode = groups_get_activity_groupmode($cm, $course);
-
-        if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', context_module::instance($cm->id))) {
-            if (isguestuser()) {
-                // shortcut - guest user does not belong into any group
-                continue;
-            }
-
-            if (is_null($modinfo->groups)) {
-                $modinfo->groups = groups_get_user_groups($course->id); // load all my groups and cache it in modinfo
-            }
-
-            // this will be slow - show only users that share group with me in this cm
-            if (empty($modinfo->groups[$cm->id])) {
-                continue;
-            }
-            $usersgroups =  groups_get_all_groups($course->id, $submission->userid, $cm->groupingid);
-            if (is_array($usersgroups)) {
-                $usersgroups = array_keys($usersgroups);
-                $intersect = array_intersect($usersgroups, $modinfo->groups[$cm->id]);
-                if (empty($intersect)) {
-                    continue;
-                }
-            }
-        }
-        $show[] = $submission;
-    }
-
-    if (empty($show)) {
-        return false;
-    }
-
-    echo $OUTPUT->heading(get_string('newsubmissions', 'assignment').':', 3);
-
-    foreach ($show as $submission) {
-        $cm = $modinfo->cms[$submission->cmid];
-        $link = $CFG->wwwroot.'/mod/assignment/view.php?id='.$cm->id;
-        print_recent_activity_note($submission->timemodified, $submission, $cm->name, $link, false, $viewfullnames);
-    }
-
-    return true;
-}
-
-
-/**
- * Returns all assignments since a given time in specified forum.
- */
-function assignment_get_recent_mod_activity(&$activities, &$index, $timestart, $courseid, $cmid, $userid=0, $groupid=0)  {
-    global $CFG, $COURSE, $USER, $DB;
-
-    if ($COURSE->id == $courseid) {
-        $course = $COURSE;
-    } else {
-        $course = $DB->get_record('course', array('id'=>$courseid));
-    }
-
-    $modinfo = get_fast_modinfo($course);
-
-    $cm = $modinfo->cms[$cmid];
-
-    $params = array();
-    if ($userid) {
-        $userselect = "AND u.id = :userid";
-        $params['userid'] = $userid;
-    } else {
-        $userselect = "";
-    }
-
-    if ($groupid) {
-        $groupselect = "AND gm.groupid = :groupid";
-        $groupjoin   = "JOIN {groups_members} gm ON  gm.userid=u.id";
-        $params['groupid'] = $groupid;
-    } else {
-        $groupselect = "";
-        $groupjoin   = "";
-    }
-
-    $params['cminstance'] = $cm->instance;
-    $params['timestart'] = $timestart;
-
-    $userfields = user_picture::fields('u', null, 'userid');
-
-    if (!$submissions = $DB->get_records_sql("SELECT asb.id, asb.timemodified,
-                                                     $userfields
-                                                FROM {assignment_submissions} asb
-                                                JOIN {assignment} a      ON a.id = asb.assignment
-                                                JOIN {user} u            ON u.id = asb.userid
-                                          $groupjoin
-                                               WHERE asb.timemodified > :timestart AND a.id = :cminstance
-                                                     $userselect $groupselect
-                                            ORDER BY asb.timemodified ASC", $params)) {
-         return;
-    }
-
-    $groupmode       = groups_get_activity_groupmode($cm, $course);
-    $cm_context      = context_module::instance($cm->id);
-    $grader          = has_capability('moodle/grade:viewall', $cm_context);
-    $accessallgroups = has_capability('moodle/site:accessallgroups', $cm_context);
-    $viewfullnames   = has_capability('moodle/site:viewfullnames', $cm_context);
-
-    if (is_null($modinfo->groups)) {
-        $modinfo->groups = groups_get_user_groups($course->id); // load all my groups and cache it in modinfo
-    }
-
-    $show = array();
-
-    foreach($submissions as $submission) {
-        if ($submission->userid == $USER->id) {
-            $show[] = $submission;
-            continue;
-        }
-        // the act of submitting of assignment may be considered private - only graders will see it if specified
-        if (empty($CFG->assignment_showrecentsubmissions)) {
-            if (!$grader) {
-                continue;
-            }
-        }
-
-        if ($groupmode == SEPARATEGROUPS and !$accessallgroups) {
-            if (isguestuser()) {
-                // shortcut - guest user does not belong into any group
-                continue;
-            }
-
-            // this will be slow - show only users that share group with me in this cm
-            if (empty($modinfo->groups[$cm->id])) {
-                continue;
-            }
-            $usersgroups = groups_get_all_groups($course->id, $cm->userid, $cm->groupingid);
-            if (is_array($usersgroups)) {
-                $usersgroups = array_keys($usersgroups);
-                $intersect = array_intersect($usersgroups, $modinfo->groups[$cm->id]);
-                if (empty($intersect)) {
-                    continue;
-                }
-            }
-        }
-        $show[] = $submission;
-    }
-
-    if (empty($show)) {
-        return;
-    }
-
-    if ($grader) {
-        require_once($CFG->libdir.'/gradelib.php');
-        $userids = array();
-        foreach ($show as $id=>$submission) {
-            $userids[] = $submission->userid;
-
-        }
-        $grades = grade_get_grades($courseid, 'mod', 'assignment', $cm->instance, $userids);
-    }
-
-    $aname = format_string($cm->name,true);
-    foreach ($show as $submission) {
-        $tmpactivity = new stdClass();
-
-        $tmpactivity->type         = 'assignment';
-        $tmpactivity->cmid         = $cm->id;
-        $tmpactivity->name         = $aname;
-        $tmpactivity->sectionnum   = $cm->sectionnum;
-        $tmpactivity->timestamp    = $submission->timemodified;
-
-        if ($grader) {
-            $tmpactivity->grade = $grades->items[0]->grades[$submission->userid]->str_long_grade;
-        }
-
-        $userfields = explode(',', user_picture::fields());
-        foreach ($userfields as $userfield) {
-            if ($userfield == 'id') {
-                $tmpactivity->user->{$userfield} = $submission->userid; // aliased in SQL above
-            } else {
-                $tmpactivity->user->{$userfield} = $submission->{$userfield};
-            }
-        }
-        $tmpactivity->user->fullname = fullname($submission, $viewfullnames);
-
-        $activities[$index++] = $tmpactivity;
-    }
-
-    return;
-}
-
-/**
- * Print recent activity from all assignments in a given course
- *
- * This is used by course/recent.php
- */
-function assignment_print_recent_mod_activity($activity, $courseid, $detail, $modnames)  {
-    global $CFG, $OUTPUT;
-
-    echo '<table border="0" cellpadding="3" cellspacing="0" class="assignment-recent">';
-
-    echo "<tr><td class=\"userpicture\" valign=\"top\">";
-    echo $OUTPUT->user_picture($activity->user);
-    echo "</td><td>";
-
-    if ($detail) {
-        $modname = $modnames[$activity->type];
-        echo '<div class="title">';
-        echo "<img src=\"" . $OUTPUT->pix_url('icon', 'assignment') . "\" ".
-             "class=\"icon\" alt=\"$modname\">";
-        echo "<a href=\"$CFG->wwwroot/mod/assignment/view.php?id={$activity->cmid}\">{$activity->name}</a>";
-        echo '</div>';
-    }
-
-    if (isset($activity->grade)) {
-        echo '<div class="grade">';
-        echo get_string('grade').': ';
-        echo $activity->grade;
-        echo '</div>';
-    }
-
-    echo '<div class="user">';
-    echo "<a href=\"$CFG->wwwroot/user/view.php?id={$activity->user->id}&amp;course=$courseid\">"
-         ."{$activity->user->fullname}</a>  - ".userdate($activity->timestamp);
-    echo '</div>';
-
-    echo "</td></tr></table>";
-}
-
-/// GENERIC SQL FUNCTIONS
-
-/**
- * Fetch info from logs
- *
- * @param $log object with properties ->info (the assignment id) and ->userid
- * @return array with assignment name and user firstname and lastname
- */
-function assignment_log_info($log) {
-    global $CFG, $DB;
-
-    return $DB->get_record_sql("SELECT a.name, u.firstname, u.lastname
-                                  FROM {assignment} a, {user} u
-                                 WHERE a.id = ? AND u.id = ?", array($log->info, $log->userid));
-}
-
-/**
- * Return list of marked submissions that have not been mailed out for currently enrolled students
- *
- * @return array
- */
-function assignment_get_unmailed_submissions($starttime, $endtime) {
-    global $CFG, $DB;
-
-    return $DB->get_records_sql("SELECT s.*, a.course, a.name
-                                   FROM {assignment_submissions} s,
-                                        {assignment} a
-                                  WHERE s.mailed = 0
-                                        AND s.timemarked <= ?
-                                        AND s.timemarked >= ?
-                                        AND s.assignment = a.id", array($endtime, $starttime));
-}
-
 /**
- * Counts all complete (real) assignment submissions by enrolled students for the given course modeule.
+ * Adds an assignment instance
  *
- * @deprecated                         Since Moodle 2.2 MDL-abc - Please do not use this function any more.
- * @param  cm_info $cm                 The course module that we wish to perform the count on.
- * @param  int     $groupid (optional) If nonzero then count is restricted to this group
- * @return int                         The number of submissions
- */
-function assignment_count_real_submissions($cm, $groupid=0) {
-    global $CFG, $DB;
-
-    // Grab the assignment type for the given course module
-    $assignmenttype = $DB->get_field($cm->modname, 'assignmenttype', array('id' => $cm->instance), MUST_EXIST);
-
-    // Create the expected class file path and class name for the returned assignemnt type
-    $filename = "{$CFG->dirroot}/mod/assignment/type/{$assignmenttype}/assignment.class.php";
-    $classname = "assignment_{$assignmenttype}";
-
-    // If the file exists and the class is not already loaded we require the class file
-    if (file_exists($filename) && !class_exists($classname)) {
-        require_once($filename);
-    }
-    // If the required class is still not loaded then we revert to assignment base
-    if (!class_exists($classname)) {
-        $classname = 'assignment_base';
-    }
-    $instance = new $classname;
-
-    // Attach the course module to the assignment type instance and then call the method for counting submissions
-    $instance->cm = $cm;
-    return $instance->count_real_submissions($groupid);
-}
-
-/**
- * Return all assignment submissions by ENROLLED students (even empty)
+ * Only used by generators so we can create old assignments to test the upgrade.
  *
- * There are also assignment type methods get_submissions() wich in the default
- * implementation simply call this function.
- * @param $sort string optional field names for the ORDER BY in the sql query
- * @param $dir string optional specifying the sort direction, defaults to DESC
- * @return array The submission objects indexed by id
+ * @param stdClass $assignment
+ * @param mod_assignment_mod_form $mform
+ * @return int intance id
  */
-function assignment_get_all_submissions($assignment, $sort="", $dir="DESC") {
-/// Return all assignment submissions by ENROLLED students (even empty)
-    global $CFG, $DB;
-
-    if ($sort == "lastname" or $sort == "firstname") {
-        $sort = "u.$sort $dir";
-    } else if (empty($sort)) {
-        $sort = "a.timemodified DESC";
-    } else {
-        $sort = "a.$sort $dir";
-    }
-
-    /* not sure this is needed at all since assignment already has a course define, so this join?
-    $select = "s.course = '$assignment->course' AND";
-    if ($assignment->course == SITEID) {
-        $select = '';
-    }*/
-    $cm = get_coursemodule_from_instance('assignment', $assignment->id, $assignment->course);
-    $context = context_module::instance($cm->id);
-    list($enroledsql, $params) = get_enrolled_sql($context, 'mod/assignment:submit');
-    $params['assignmentid'] = $assignment->id;
-    return $DB->get_records_sql("SELECT a.*
-                                    FROM {assignment_submissions} a
-                                    INNER JOIN (". $enroledsql .") u ON u.id = a.userid
-                                  WHERE u.id = a.userid
-                                        AND a.assignment = :assignmentid
-                                  ORDER BY $sort", $params);
+function assignment_add_instance($assignment, $mform = null) {
+    global $DB;
 
+    $assignment->timemodified = time();
+    $assignment->courseid = $assignment->course;
+    $returnid = $DB->insert_record("assignment", $assignment);
+    $assignment->id = $returnid;
+    return $returnid;
 }
 
 /**
- * Add a get_coursemodule_info function in case any assignment type wants to add 'extra' information
- * for the course (see resource).
- *
- * Given a course_module object, this function returns any "extra" information that may be needed
- * when printing this activity in a course listing.  See get_array_of_activities() in course/lib.php.
+ * Deletes an assignment instance
  *
- * @param stdClass $coursemodule object The coursemodule object (record).
- * @return cached_cm_info An object on information that the courses will know about (most noticeably, an icon).
+ * @param $id
  */
-function assignment_get_coursemodule_info($coursemodule) {
+function assignment_delete_instance($id){
     global $CFG, $DB;
 
-    if (! $assignment = $DB->get_record('assignment', array('id'=>$coursemodule->instance),
-            'id, assignmenttype, name, intro, introformat')) {
-        return false;
-    }
-
-    $libfile = "$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php";
-
-    if (file_exists($libfile)) {
-        require_once($libfile);
-        $assignmentclass = "assignment_$assignment->assignmenttype";
-        $ass = new $assignmentclass('staticonly');
-        if (!($result = $ass->get_coursemodule_info($coursemodule))) {
-            $result = new cached_cm_info();
-            $result->name = $assignment->name;
-        }
-        if ($coursemodule->showdescription) {
-            // Convert intro to html. Do not filter cached version, filters run at display time.
-            $result->content = format_module_intro('assignment', $assignment, $coursemodule->id, false);
-        }
-        return $result;
-    } else {
-        debugging('Incorrect assignment type: '.$assignment->assignmenttype);
+    if (! $assignment = $DB->get_record('assignment', array('id'=>$id))) {
         return false;
     }
-}
-
-
-
-/// OTHER GENERAL FUNCTIONS FOR ASSIGNMENTS  ///////////////////////////////////////
-
-/**
- * Returns an array of installed assignment types indexed and sorted by name
- *
- * @return array The index is the name of the assignment type, the value its full name from the language strings
- */
-function assignment_types() {
-    $types = array();
-    $names = core_component::get_plugin_list('assignment');
-    foreach ($names as $name=>$dir) {
-        $types[$name] = get_string('type'.$name, 'assignment');
-
-        // ugly hack to support pluggable assignment type titles..
-        if ($types[$name] == '[[type'.$name.']]') {
-            $types[$name] = get_string('type'.$name, 'assignment_'.$name);
-        }
-    }
-    asort($types);
-    return $types;
-}
-
-function assignment_print_overview($courses, &$htmlarray) {
-    global $USER, $CFG, $DB;
-    require_once($CFG->libdir.'/gradelib.php');
-
-    if (empty($courses) || !is_array($courses) || count($courses) == 0) {
-        return array();
-    }
-
-    if (!$assignments = get_all_instances_in_courses('assignment',$courses)) {
-        return;
-    }
-
-    $assignmentids = array();
-
-    // Do assignment_base::isopen() here without loading the whole thing for speed
-    foreach ($assignments as $key => $assignment) {
-        $time = time();
-        if ($assignment->timedue) {
-            if ($assignment->preventlate) {
-                $isopen = ($assignment->timeavailable <= $time && $time <= $assignment->timedue);
-            } else {
-                $isopen = ($assignment->timeavailable <= $time);
-            }
-        }
-        if (empty($isopen) || empty($assignment->timedue)) {
-            unset($assignments[$key]);
-        } else {
-            $assignmentids[] = $assignment->id;
-        }
-    }
-
-    if (empty($assignmentids)){
-        // no assignments to look at - we're done
-        return true;
-    }
-
-    $strduedate = get_string('duedate', 'assignment');
-    $strduedateno = get_string('duedateno', 'assignment');
-    $strgraded = get_string('graded', 'assignment');
-    $strnotgradedyet = get_string('notgradedyet', 'assignment');
-    $strnotsubmittedyet = get_string('notsubmittedyet', 'assignment');
-    $strsubmitted = get_string('submitted', 'assignment');
-    $strassignment = get_string('modulename', 'assignment');
-    $strreviewed = get_string('reviewed','assignment');
-
-
-    // NOTE: we do all possible database work here *outside* of the loop to ensure this scales
-    //
-    list($sqlassignmentids, $assignmentidparams) = $DB->get_in_or_equal($assignmentids);
-
-    // build up and array of unmarked submissions indexed by assignment id/ userid
-    // for use where the user has grading rights on assignment
-    $rs = $DB->get_recordset_sql("SELECT id, assignment, userid
-                            FROM {assignment_submissions}
-                            WHERE teacher = 0 AND timemarked = 0
-                            AND assignment $sqlassignmentids", $assignmentidparams);
-
-    $unmarkedsubmissions = array();
-    foreach ($rs as $rd) {
-        $unmarkedsubmissions[$rd->assignment][$rd->userid] = $rd->id;
-    }
-    $rs->close();
-
-
-    // get all user submissions, indexed by assignment id
-    $mysubmissions = $DB->get_records_sql("SELECT assignment, timemarked, teacher, grade
-                                      FROM {assignment_submissions}
-                                      WHERE userid = ? AND
-                                      assignment $sqlassignmentids", array_merge(array($USER->id), $assignmentidparams));
-
-    foreach ($assignments as $assignment) {
-        $grading_info = grade_get_grades($assignment->course, 'mod', 'assignment', $assignment->id, $USER->id);
-        $final_grade = $grading_info->items[0]->grades[$USER->id];
-
-        $str = '<div class="assignment overview"><div class="name">'.$strassignment. ': '.
-               '<a '.($assignment->visible ? '':' class="dimmed"').
-               'title="'.$strassignment.'" href="'.$CFG->wwwroot.
-               '/mod/assignment/view.php?id='.$assignment->coursemodule.'">'.
-               $assignment->name.'</a></div>';
-        if ($assignment->timedue) {
-            $str .= '<div class="info">'.$strduedate.': '.userdate($assignment->timedue).'</div>';
-        } else {
-            $str .= '<div class="info">'.$strduedateno.'</div>';
-        }
-        $context = context_module::instance($assignment->coursemodule);
-        if (has_capability('mod/assignment:grade', $context)) {
-
-            // count how many people can submit
-            $submissions = 0; // init
-            if ($students = get_enrolled_users($context, 'mod/assignment:view', 0, 'u.id')) {
-                foreach ($students as $student) {
-                    if (isset($unmarkedsubmissions[$assignment->id][$student->id])) {
-                        $submissions++;
-                    }
-                }
-            }
-
-            if ($submissions) {
-                $link = new moodle_url('/mod/assignment/submissions.php', array('id'=>$assignment->coursemodule));
-                $str .= '<div class="details"><a href="'.$link.'">'.get_string('submissionsnotgraded', 'assignment', $submissions).'</a></div>';
-            }
-        } else {
-            $str .= '<div class="details">';
-            if (isset($mysubmissions[$assignment->id])) {
-
-                $submission = $mysubmissions[$assignment->id];
-
-                if ($submission->teacher == 0 && $submission->timemarked == 0 && !$final_grade->grade) {
-                    $str .= $strsubmitted . ', ' . $strnotgradedyet;
-                } else if ($submission->grade <= 0 && !$final_grade->grade) {
-                    $str .= $strsubmitted . ', ' . $strreviewed;
-                } else {
-                    $str .= $strsubmitted . ', ' . $strgraded;
-                }
-            } else {
-                $str .= $strnotsubmittedyet . ' ' . assignment_display_lateness(time(), $assignment->timedue);
-            }
-            $str .= '</div>';
-        }
-        $str .= '</div>';
-        if (empty($htmlarray[$assignment->course]['assignment'])) {
-            $htmlarray[$assignment->course]['assignment'] = $str;
-        } else {
-            $htmlarray[$assignment->course]['assignment'] .= $str;
-        }
-    }
-}
-
-function assignment_display_lateness($timesubmitted, $timedue) {
-    if (!$timedue) {
-        return '';
-    }
-    $time = $timedue - $timesubmitted;
-    if ($time < 0) {
-        $timetext = get_string('late', 'assignment', format_time($time));
-        return ' (<span class="late">'.$timetext.'</span>)';
-    } else {
-        $timetext = get_string('early', 'assignment', format_time($time));
-        return ' (<span class="early">'.$timetext.'</span>)';
-    }
-}
-
-function assignment_get_view_actions() {
-    return array('view');
-}
-
-function assignment_get_post_actions() {
-    return array('upload');
-}
-
-function assignment_get_types() {
-    global $CFG;
-    $types = array();
-
-    $type = new stdClass();
-    $type->modclass = MOD_CLASS_ACTIVITY;
-    $type->type = "assignment_group_start";
-    $type->typestr = '--'.get_string('modulenameplural', 'assignment');
-    $types[] = $type;
-
-    $standardassignments = array('upload','online','uploadsingle','offline');
-    foreach ($standardassignments as $assignmenttype) {
-        $type = new stdClass();
-        $type->modclass = MOD_CLASS_ACTIVITY;
-        $type->type = "assignment&amp;type=$assignmenttype";
-        $type->typestr = get_string("type$assignmenttype", 'assignment');
-        $types[] = $type;
-    }
-
-    /// Drop-in extra assignment types
-    $assignmenttypes = core_component::get_plugin_list('assignment');
-    foreach ($assignmenttypes as $assignmenttype=>$fulldir) {
-        if (!empty($CFG->{'assignment_hide_'.$assignmenttype})) {  // Not wanted
-            continue;
-        }
-        if (!in_array($assignmenttype, $standardassignments)) {
-            $type = new stdClass();
-            $type->modclass = MOD_CLASS_ACTIVITY;
-            $type->type = "assignment&amp;type=$assignmenttype";
-            $type->typestr = get_string("type$assignmenttype", 'assignment_'.$assignmenttype);
-            $types[] = $type;
-        }
-    }
-
-    $type = new stdClass();
-    $type->modclass = MOD_CLASS_ACTIVITY;
-    $type->type = "assignment_group_end";
-    $type->typestr = '--';
-    $types[] = $type;
-
-    return $types;
-}
-
-/**
- * Removes all grades from gradebook
- *
- * @param int $courseid The ID of the course to reset
- * @param string $type Optional type of assignment to limit the reset to a particular assignment type
- */
-function assignment_reset_gradebook($courseid, $type='') {
-    global $CFG, $DB;
 
-    $params = array('courseid'=>$courseid);
-    if ($type) {
-        $type = "AND a.assignmenttype= :type";
-        $params['type'] = $type;
+    $result = true;
+    // Now get rid of all files
+    $fs = get_file_storage();
+    if ($cm = get_coursemodule_from_instance('assignment', $assignment->id)) {
+        $context = context_module::instance($cm->id);
+        $fs->delete_area_files($context->id);
     }
 
-    $sql = "SELECT a.*, cm.idnumber as cmidnumber, a.course as courseid
-              FROM {assignment} a, {course_modules} cm, {modules} m
-             WHERE m.name='assignment' AND m.id=cm.module AND cm.instance=a.id AND a.course=:courseid $type";
-
-    if ($assignments = $DB->get_records_sql($sql, $params)) {
-        foreach ($assignments as $assignment) {
-            assignment_grade_item_update($assignment, 'reset');
-        }
+    if (! $DB->delete_records('assignment_submissions', array('assignment'=>$assignment->id))) {
+        $result = false;
     }
-}
 
-/**
- * This function is used by the reset_course_userdata function in moodlelib.
- * This function will remove all posts from the specified assignment
- * and clean up any related data.
- * @param $data the data submitted from the reset course.
- * @return array status array
- */
-function assignment_reset_userdata($data) {
-    global $CFG;
-
-    $status = array();
-    foreach (core_component::get_plugin_list('assignment') as $type=>$dir) {
-        require_once("$dir/assignment.class.php");
-        $assignmentclass = "assignment_$type";
-        $ass = new $assignmentclass();
-        $status = array_merge($status, $ass->reset_userdata($data));
+    if (! $DB->delete_records('event', array('modulename'=>'assignment', 'instance'=>$assignment->id))) {
+        $result = false;
     }
 
-    // Updating dates - shift may be negative too.
-    if ($data->timeshift) {
-        shift_course_mod_dates('assignment',
-                                array('timedue', 'timeavailable'),
-                                $data->timeshift,
-                                $data->courseid);
-        $status[] = array('component' => get_string('modulenameplural', 'assignment'),
-                          'item' => get_string('datechanged'),
-                          'error' => false);
+    if (! $DB->delete_records('assignment', array('id'=>$assignment->id))) {
+        $result = false;
     }
 
-    return $status;
-}
-
-/**
- * Implementation of the function for printing the form elements that control
- * whether the course reset functionality affects the assignment.
- * @param $mform form passed by reference
- */
-function assignment_reset_course_form_definition(&$mform) {
-    $mform->addElement('header', 'assignmentheader', get_string('modulenameplural', 'assignment'));
-    $mform->addElement('advcheckbox', 'reset_assignment_submissions', get_string('deleteallsubmissions','assignment'));
-}
-
-/**
- * Course reset form defaults.
- */
-function assignment_reset_course_form_defaults($course) {
-    return array('reset_assignment_submissions'=>1);
-}
+    grade_update('mod/assignment', $assignment->course, 'mod', 'assignment', $assignment->id, 0, NULL, array('deleted'=>1));
 
-/**
- * Returns all other caps used in module
- */
-function assignment_get_extra_capabilities() {
-    return array('moodle/site:accessallgroups', 'moodle/site:viewfullnames', 'moodle/grade:managegradingforms');
+    return $result;
 }
 
 /**
@@ -3924,162 +87,8 @@ function assignment_get_extra_capabilities() {
  */
 function assignment_supports($feature) {
     switch($feature) {
-        case FEATURE_GROUPS:                  return true;
-        case FEATURE_GROUPINGS:               return true;
-        case FEATURE_GROUPMEMBERSONLY:        return true;
-        case FEATURE_MOD_INTRO:               return true;
-        case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
-        case FEATURE_GRADE_HAS_GRADE:         return true;
-        case FEATURE_GRADE_OUTCOMES:          return true;
-        case FEATURE_GRADE_HAS_GRADE:         return true;
         case FEATURE_BACKUP_MOODLE2:          return true;
-        case FEATURE_SHOW_DESCRIPTION:        return true;
-        case FEATURE_ADVANCED_GRADING:        return true;
-        case FEATURE_PLAGIARISM:              return true;
 
         default: return null;
     }
 }
-
-/**
- * Adds module specific settings to the settings block
- *
- * @param settings_navigation $settings The settings navigation object
- * @param navigation_node $assignmentnode The node to add module settings to
- */
-function assignment_extend_settings_navigation(settings_navigation $settings, navigation_node $assignmentnode) {
-    global $PAGE, $DB, $USER, $CFG;
-
-    $assignmentrow = $DB->get_record("assignment", array("id" => $PAGE->cm->instance));
-
-    $classfile = "$CFG->dirroot/mod/assignment/type/$assignmentrow->assignmenttype/assignment.class.php";
-    if (!file_exists($classfile)) {
-        return;
-    }
-    require_once($classfile);
-
-    $assignmentclass = 'assignment_'.$assignmentrow->assignmenttype;
-    $assignmentinstance = new $assignmentclass($PAGE->cm->id, $assignmentrow, $PAGE->cm, $PAGE->course);
-
-    $allgroups = false;
-
-    // Add assignment submission information
-    if (has_capability('mod/assignment:grade', $PAGE->cm->context)) {
-        if ($allgroups && has_capability('moodle/site:accessallgroups', $PAGE->cm->context)) {
-            $group = 0;
-        } else {
-            $group = groups_get_activity_group($PAGE->cm);
-        }
-        $link = new moodle_url('/mod/assignment/submissions.php', array('id'=>$PAGE->cm->id));
-        if ($assignmentrow->assignmenttype == 'offline') {
-            $string = get_string('viewfeedback', 'assignment');
-        } else if ($count = $assignmentinstance->count_real_submissions($group)) {
-            $string = get_string('viewsubmissions', 'assignment', $count);
-        } else {
-            $string = get_string('noattempts', 'assignment');
-        }
-        $assignmentnode->add($string, $link, navigation_node::TYPE_SETTING);
-    }
-
-    if (is_object($assignmentinstance) && method_exists($assignmentinstance, 'extend_settings_navigation')) {
-        $assignmentinstance->extend_settings_navigation($assignmentnode);
-    }
-}
-
-/**
- * generate zip file from array of given files
- * @param array $filesforzipping - array of files to pass into archive_to_pathname
- * @return path of temp file - note this returned file does not have a .zip extension - it is a temp file.
- */
-function assignment_pack_files($filesforzipping) {
-        global $CFG;
-        //create path for new zip file.
-        $tempzip = tempnam($CFG->tempdir.'/', 'assignment_');
-        //zip files
-        $zipper = new zip_packer();
-        if ($zipper->archive_to_pathname($filesforzipping, $tempzip)) {
-            return $tempzip;
-        }
-        return false;
-}
-
-/**
- * Lists all file areas current user may browse
- *
- * @package  mod_assignment
- * @category files
- * @param stdClass $course course object
- * @param stdClass $cm course module object
- * @param stdClass $context context object
- * @return array available file areas
- */
-function assignment_get_file_areas($course, $cm, $context) {
-    $areas = array();
-    if (has_capability('moodle/course:managefiles', $context)) {
-        $areas['submission'] = get_string('assignmentsubmission', 'assignment');
-    }
-    return $areas;
-}
-
-/**
- * File browsing support for assignment module.
- *
- * @param file_browser $browser
- * @param array $areas
- * @param stdClass $course
- * @param cm_info $cm
- * @param context $context
- * @param string $filearea
- * @param int $itemid
- * @param string $filepath
- * @param string $filename
- * @return file_info_stored file_info_stored instance or null if not found
- */
-function assignment_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
-    global $CFG, $DB, $USER;
-
-    if ($context->contextlevel != CONTEXT_MODULE || $filearea != 'submission') {
-        return null;
-    }
-    if (!$submission = $DB->get_record('assignment_submissions', array('id' => $itemid))) {
-        return null;
-    }
-    if (!(($submission->userid == $USER->id && has_capability('mod/assignment:view', $context))
-            || has_capability('mod/assignment:grade', $context))) {
-        // no permission to view this submission
-        return null;
-    }
-
-    $fs = get_file_storage();
-    $filepath = is_null($filepath) ? '/' : $filepath;
-    $filename = is_null($filename) ? '.' : $filename;
-    if (!($storedfile = $fs->get_file($context->id, 'mod_assignment', $filearea, $itemid, $filepath, $filename))) {
-        return null;
-    }
-    $urlbase = $CFG->wwwroot.'/pluginfile.php';
-    return new file_info_stored($browser, $context, $storedfile, $urlbase, $filearea, $itemid, true, true, false);
-}
-
-/**
- * Return a list of page types
- * @param string $pagetype current page type
- * @param stdClass $parentcontext Block's parent context
- * @param stdClass $currentcontext Current context of block
- */
-function assignment_page_type_list($pagetype, $parentcontext, $currentcontext) {
-    $module_pagetype = array(
-        'mod-assignment-*'=>get_string('page-mod-assignment-x', 'assignment'),
-        'mod-assignment-view'=>get_string('page-mod-assignment-view', 'assignment'),
-        'mod-assignment-submissions'=>get_string('page-mod-assignment-submissions', 'assignment')
-    );
-    return $module_pagetype;
-}
-
-/**
- * Lists all gradable areas for the advanced grading methods gramework
- *
- * @return array
- */
-function assignment_grading_areas_list() {
-    return array('submission' => get_string('submissions', 'mod_assignment'));
-}
diff --git a/mod/assignment/locallib.php b/mod/assignment/locallib.php
deleted file mode 100644 (file)
index 0202cad..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-<?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 all the functions that aren't needed by core moodle
-// but start becoming required once we're actually inside the assignment module.
-
-require_once($CFG->dirroot . '/mod/assignment/lib.php');
-require_once($CFG->libdir . '/portfolio/caller.php');
-
-/**
- * @package   mod-assignment
- * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class assignment_portfolio_caller extends portfolio_module_caller_base {
-
-    /**
-    * the assignment subclass
-    */
-    private $assignment;
-
-    /**
-    * the file to include when waking up to load the assignment subclass def
-    */
-    private $assignmentfile;
-
-    /** @var int callback arg - the id of submission we export */
-    protected $submissionid;
-
-    /**
-    * callback arg for a single file export
-    */
-    protected $fileid;
-
-    public static function expected_callbackargs() {
-        return array(
-            'id'           => true,
-            'submissionid' => false,
-            'fileid'       => false,
-        );
-    }
-
-    /**
-     * Load data needed for the portfolio export
-     *
-     * If the assignment type implements portfolio_load_data(), the processing is delegated
-     * to it. Otherwise, the caller must provide either fileid (to export single file) or
-     * submissionid (to export all data attached to the given submission) via callback arguments.
-     */
-    public function load_data() {
-        global $DB, $CFG;
-
-        if (! $this->cm = get_coursemodule_from_id('assignment', $this->id)) {
-            throw new portfolio_caller_exception('invalidcoursemodule');
-        }
-
-        if (! $assignment = $DB->get_record("assignment", array("id"=>$this->cm->instance))) {
-            throw new portfolio_caller_exception('invalidid', 'assignment');
-        }
-
-        $this->assignmentfile = '/mod/assignment/type/' . $assignment->assignmenttype . '/assignment.class.php';
-        require_once($CFG->dirroot . $this->assignmentfile);
-        $assignmentclass = "assignment_$assignment->assignmenttype";
-
-        $this->assignment = new $assignmentclass($this->cm->id, $assignment, $this->cm);
-
-        if (!$this->assignment->portfolio_exportable()) {
-            throw new portfolio_caller_exception('notexportable', 'portfolio', $this->get_return_url());
-        }
-
-        if (is_callable(array($this->assignment, 'portfolio_load_data'))) {
-            return $this->assignment->portfolio_load_data($this);
-        }
-
-        if (empty($this->fileid)) {
-            if (empty($this->submissionid)) {
-                throw new portfolio_caller_exception('invalidfileandsubmissionid', 'mod_assignment');
-            }
-
-            if (! $submission = $DB->get_record('assignment_submissions', array('assignment'=>$assignment->id, 'id'=>$this->submissionid))) {
-                throw new portfolio_caller_exception('invalidsubmissionid', 'mod_assignment');
-            }
-
-            $submissionid = $submission->id;
-
-        } else {
-            // once we know the file id, we do not need the submission
-            $submissionid = null;
-        }
-
-        $this->set_file_and_format_data($this->fileid, $this->assignment->context->id, 'mod_assignment', 'submission', $submissionid, 'timemodified', false);
-    }
-
-