Merge branch 'MDL-40056-master' of git://github.com/ankitagarwal/moodle
authorDamyon Wiese <damyon@moodle.com>
Tue, 14 Jan 2014 05:14:09 +0000 (13:14 +0800)
committerDamyon Wiese <damyon@moodle.com>
Tue, 14 Jan 2014 05:14:09 +0000 (13:14 +0800)
126 files changed:
admin/tool/multilangupgrade/lang/en/tool_multilangupgrade.php
admin/tool/spamcleaner/lang/en/tool_spamcleaner.php
admin/tool/xmldb/lang/en/tool_xmldb.php
blocks/activity_modules/tests/behat/block_activity_modules.feature
blocks/private_files/styles.css [new file with mode: 0644]
blocks/settings/lang/en/block_settings.php
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/admin.php
lang/en/badges.php
lang/en/block.php
lang/en/completion.php
lang/en/error.php
lang/en/grading.php
lang/en/group.php
lang/en/moodle.php
lang/en/question.php
lang/en/role.php
lang/en/webservice.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/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
message/output/email/lang/en/message_email.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/data/lang/en/data.php
mod/feedback/lang/en/feedback.php
mod/folder/lang/en/folder.php
mod/glossary/lang/en/glossary.php
mod/glossary/tests/behat/entries_require_approval.feature
mod/lesson/lang/en/lesson.php
mod/lti/lang/en/lti.php
mod/quiz/lang/en/quiz.php
mod/quiz/startattempt.php
mod/quiz/summary.php
mod/scorm/lang/en/scorm.php
mod/scorm/request.js
mod/wiki/edit_form.php
mod/wiki/pagelib.php
portfolio/boxnet/lang/en/portfolio_boxnet.php
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 f874a46..62a4426 100644 (file)
@@ -23,5 +23,7 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$string['multilangupgradeinfo'] = 'The multilang filter syntax was changed in 1.8, &lt;lang&gt; tag is not supported any more. <br /><br />Example: &lt;span lang="en" class="multilang">Hello!&lt;/span&gt;&lt;span lang="es" class="multilang">Hola!&lt;/span&gt;<br /><br /><strong>Do you want to upgrade the syntax in all existing texts now?</strong>';
+$string['multilangupgradeinfo'] = '<p>The multilang filter syntax was changed in 1.8 and so the &lt;lang&gt; tag is not supported any more.</p>
+<p>Example: &lt;span lang="en" class="multilang"&gt;Hello!&lt;/span&gt;&lt;span lang="es" class="multilang"&gt;Hola!&lt;/span&gt;</p>
+<p>Do you want to upgrade the syntax in all existing texts now?</p>';
 $string['pluginname'] = 'Multilang upgrade';
index df6b4a3..d9f5918 100644 (file)
@@ -27,7 +27,8 @@ $string['pluginname'] = 'Spam cleaner';
 $string['spamauto'] = 'Autodetect common spam patterns';
 $string['spamcannotdelete'] = 'Cannot delete this user';
 $string['spamcannotfinduser'] = 'No users matching your search';
-$string['spamcleanerintro'] = 'This script allows you to search all user profiles for certain strings and then delete those accounts which are obviously created by spammers.  You can search for multiple keywords using commas (eg casino, porn)<br /><br />Moodle docs has more information about <a href="http://docs.moodle.org/en/Reducing_spam_in_Moodle">Reducing spam in Moodle</a>.';
+$string['spamcleanerintro'] = '<p>This script allows you to search all user profiles for certain strings and then delete those accounts which are obviously created by spammers. You can search for multiple keywords using commas (e.g. casino, porn).</p>
+<p>For further information, see the documentation <a href="http://docs.moodle.org/en/Reducing_spam_in_Moodle">Reducing spam in Moodle</a>.</p>';
 $string['spamdeleteall'] = 'Delete all these user accounts';
 $string['spamdeleteallconfirm'] = 'Are you sure you want to delete all these user accounts?  You can not undo this.';
 $string['spamdeleteconfirm'] = 'Are you sure you want to delete this entry?  You can not undo this.';
index f89293f..638941f 100644 (file)
@@ -210,7 +210,11 @@ $string['wronglengthforenum'] = 'Incorrect length for enum field';
 $string['wrongnumberofreffields'] = 'Wrong number of reference fields';
 $string['wrongreservedwords'] = 'Currently used reserved words<br />(note that table names aren\'t important if using $CFG->prefix)';
 $string['wrongoraclesemantics'] = 'Wrong Oracle BYTE semantics found';
-$string['yesmissingindexesfound'] = 'Some missing indexes have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to create all them (don\'t forget to backup your data before doing that).<br /><br />After doing that, it\'s highly recommended to execute this utility again to check that no more missing indexes are found.';
-$string['yeswrongdefaultsfound'] = 'Some inconsistent defaults have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to fix them all (don\'t forget to backup your data before doing that).<br /><br />After doing that, it\'s highly recommended to execute this utility again to check that no more inconsistent defaults are found.';
-$string['yeswrongintsfound'] = 'Some wrong integers have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to create all them (don\'t forget to backup your data before doing that).<br /><br />After doing that, it\'s highly recommended to execute this utility again to check that no more wrong integers are found.';
-$string['yeswrongoraclesemanticsfound'] = 'Some Oracle columns using BYTE semantics have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to create all them (don\'t forget to backup your data before doing that).<br /><br />After doing that, it\'s highly recommended to execute this utility again to check that no more wrong semantics are found.';
+$string['yesmissingindexesfound'] = '<p>Some missing indexes have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to create all of them. Remember to backup your data first!</p>
+<p>After doing that, it\'s highly recommended to execute this utility again to check that no more missing indexes are found.</p>';
+$string['yeswrongdefaultsfound'] = '<p>Some inconsistent defaults have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to fix them all. Remember to backup your data first!</p>
+<p>After doing that, it\'s highly recommended to execute this utility again to check that no more inconsistent defaults are found.</p>';
+$string['yeswrongintsfound'] = '<p>Some wrong integers have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to create all them. Remember to backup your data first!</p>
+<p>After doing that, it\'s highly recommended to execute this utility again to check that no more wrong integers are found.</p>';
+$string['yeswrongoraclesemanticsfound'] = '<p>Some Oracle columns using BYTE semantics have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to create all them. Remember to backup your data first!</p>
+<p>After doing that, it\'s highly recommended to execute this utility again to check that no more wrong semantics are found.</p>';
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 fd3f2b3..7442de8 100644 (file)
@@ -27,4 +27,4 @@
 $string['enabledock'] = 'Allow the user to dock this block';
 $string['pluginname'] = 'Administration';
 $string['settings:addinstance'] = 'Add a new administration block';
-$string['settings:myaddinstance'] = 'Add a new settings block to My home';
+$string['settings:myaddinstance'] = 'Add a new administration block to My home';
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 7e79c1d..d3671be 100644 (file)
@@ -89,7 +89,7 @@ $string['bloglevel'] = 'Blog visibility';
 $string['bookmarkadded'] = 'Bookmark added.';
 $string['bookmarkalreadyexists'] = 'You have already bookmarked this page.';
 $string['bookmarkdeleted'] = 'Bookmark deleted.';
-$string['bookmarkthispage'] = 'bookmark this page';
+$string['bookmarkthispage'] = 'Bookmark this page';
 $string['cachejs'] = 'Cache Javascript';
 $string['cachejs_help'] = 'Javascript caching and compression greatly improves page loading performance. it is strongly recommended for production sites. Developers will probably want to disable this feature.';
 $string['cachetext'] = 'Text cache lifetime';
@@ -231,7 +231,7 @@ $string['configfrontpageloggedin'] = 'The items selected above will be displayed
 $string['configfullnamedisplay'] = 'This defines how names are shown when they are displayed in full. The default value, "language", leaves it to the string "fullnamedisplay" in the current language pack to decide. Some languages have different name display conventions.
 
 For most mono-lingual sites the most efficient setting is "firstname lastname", but you may choose to hide surnames altogether. Placeholders that can be used are: firstname, lastname, firstnamephonetic, lastnamephonetic, middlename, and alternatename.';
-$string['configgeoipfile'] = 'Location of GeoIP City binary data file. This file is not part of Moodle distribution and must be obtained separately from <a href="http://www.maxmind.com/">MaxMind</a>. You can either buy a commercial version or use the free version.<br />Simply download <a href="http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz" >http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz</a> and extract it into "{$a}" directory on your server.';
+$string['configgeoipfile'] = 'Location of GeoIP City binary data file. This file is not part of Moodle distribution and must be obtained separately from <a href="http://www.maxmind.com/">MaxMind</a>. You can either buy a commercial version or use the free version. Simply download <a href="http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz" >http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz</a> and extract it into "{$a}" directory on your server.';
 $string['configgetremoteaddrconf'] = 'If your server is behind a reverse proxy, you can use this setting to specify which HTTP headers can be trusted to contain the remote IP address. The headers are read in order, using the first one that is available.';
 $string['configgradebookroles'] = 'This setting allows you to control who appears on the gradebook.  Users need to have at least one of these roles in a course to be shown in the gradebook for that course.';
 $string['configgradeexport'] = 'Choose which gradebook export formats are your primary methods for exporting grades.  Chosen plugins will then set and use a "last exported" field for every grade.  For example, this might result in exported records being identified as being "new" or "updated".  If you are not sure about this then leave everything unchecked.';
@@ -624,7 +624,7 @@ $string['latinexcelexport'] = 'Excel encoding';
 $string['legacyfilesaddallowed'] = 'Allow adding to legacy course files';
 $string['legacyfilesaddallowed_help'] = 'If a course has legacy course files, allow new files and folders to be added to it.';
 $string['legacyfilesinnewcourses'] = 'Legacy course files in new courses';
-$string['legacyfilesinnewcourses_help'] = 'By default legacy course files areas are available only in upgraded courses. Please note some features like single activity backup/restore are not compatible with this settings.';
+$string['legacyfilesinnewcourses_help'] = 'By default, legacy course files areas are available in upgraded courses only. Please note that some features such as activity backup and restore are not compatible with this setting.';
 $string['licensesettings'] = 'Licence settings';
 $string['linkadmincategories'] = 'Link admin categories';
 $string['linkadmincategories_help'] = 'If enabled admin setting categories will be displayed as links in the navigation and will lead to the admin category pages.';
@@ -755,7 +755,7 @@ $string['navshowcategories'] = 'Show course categories';
 $string['navshowmycoursecategories'] = 'Show my course categories';
 $string['navshowmycoursecategories_help'] = 'If enabled courses in the users my courses branch will be shown in categories.';
 $string['navsortmycoursessort'] = 'Sort my courses';
-$string['navsortmycoursessort_help'] = 'This determines whether courses are listed under My courses according to the sort order (i.e. the order set in Settings > Site Administration > Courses > Add/edit courses) or alphabetically by course setting.';
+$string['navsortmycoursessort_help'] = 'This determines whether courses are listed under My courses according to the sort order (i.e. the order set in Site administration > Courses > Manage courses and categories) or alphabetically by course setting.';
 $string['neverdeleteruns'] = 'Never delete runs';
 $string['nobookmarksforuser'] = 'You do not have any bookmarks.';
 $string['nodatabase'] = 'No database';
@@ -1092,11 +1092,10 @@ This warning is often caused by unzipping a standard Moodle package over a previ
 This warning can also be caused by an incomplete checkout or update operation from the Git repository, in which case you may just have to wait for the operation to complete, or perhaps run the appropriate clean-up command and retry the operation.
 
 You can find more information in upgrade documentation at <a href="{$a}">{$a}</a>.';
-$string['upgradesure'] = 'Your Moodle files have been changed, and you are about to automatically upgrade your server to this version: <br /><br />
-<strong>{$a}</strong> <br /><br />
-Once you do this you can not go back again. <br /><br />
-Please note that this process can take a long time. <br /><br />
-Are you sure you want to upgrade this server to this version?';
+$string['upgradesure'] = '<p>Your Moodle files have been changed, and you are about to automatically upgrade your server to this version:</p>
+<p><strong>{$a}</strong></p>
+<p>Once you do this you can not go back again. Please note that this process can take a long time.</p>
+<p>Are you sure you want to upgrade this server to this version?</p>';
 $string['upgradetimedout'] = 'Upgrade timed out, please restart the upgrade.';
 $string['upgrade197notice'] = '<p>Moodle 1.9.7 contains a number of security fixes to user passwords and backups to protect the user data on your site. As a result some of your settings and permissions relating to backups may have changed.<br />
 See the <a href="http://docs.moodle.org/dev/Moodle_1.9.7_release_notes" target="_blank">Moodle 1.9.7 release notes</a> for full details.</p>';
index 099d8e7..9ad8f9e 100644 (file)
@@ -282,9 +282,9 @@ $string['makeprivate'] = 'Make private';
 $string['makepublic'] = 'Make public';
 $string['managebadges'] = 'Manage badges';
 $string['message'] = 'Message body';
-$string['messagebody'] = '<p>You have been awarded a badge "%badgename%"!</p>
+$string['messagebody'] = '<p>You have been awarded the badge "%badgename%"!</p>
 <p>More information about this badge can be found at %badgelink%.</p>
-<p>If there is no badge attached to this email, you can manage and download it from {$a} page.</p>';
+<p>You can manage and download the badge from {$a}.</p>';
 $string['messagesubject'] = 'Congratulations! You just earned a badge!';
 $string['method'] = 'This criterion is complete when...';
 $string['mingrade'] = 'Minimum grade required';
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 a6b1f3c..fc9bc9e 100644 (file)
@@ -124,7 +124,7 @@ $string['err_nocourses'] = 'Course completion is not enabled for any other cours
 $string['err_nograde'] = 'A course pass grade has not been set for this course. To enable this criteria type you must create a pass grade for this course.';
 $string['err_noroles'] = 'There are no roles with the capability moodle/course:markcomplete in this course.';
 $string['err_nousers'] = 'There are no students on this course or group for whom completion information is displayed. (By default, completion information is displayed only for students, so if there are no students, you will see this error. Administrators can alter this option via the admin screens.)';
-$string['err_settingslocked'] = 'One or more students have already completed a criteria so the settings have been locked. Unlocking the completion criteria settings will delete any existing user data and may cause confusion.';
+$string['err_settingslocked'] = 'One or more students have already completed a criterion so the settings have been locked. Unlocking the completion criteria settings will delete any existing user data and may cause confusion.';
 $string['err_system'] = 'An internal error occurred in the completion system. (System administrators can enable debugging information to see more detail.)';
 $string['eventcoursecompleted'] = 'Course completed';
 $string['eventcoursecompletionupdated'] = 'Course completion updated';
index 2739a36..b5c1c3c 100644 (file)
@@ -194,8 +194,8 @@ $string['dbconnectionfailed'] = '<p>Error: Database connection failed</p>
 $string['dbdriverproblem'] = '<p>Error: database driver problem detected</p>
 <p>The site administrator should verify server configuration</p><p>{$a}</p>';
 $string['dbsessionbroken'] = 'Serious database session problem detected.<br /><br />Please notify server administrator.';
-$string['dbsessionhandlerproblem'] = 'Setting up of database session failed.<br /><br />Please notify server administrator.';
-$string['dbsessionmysqlpacketsize'] = 'Serious session error detected.<br /><br />Please notify administrator, this problem is most probably caused by small value in max_allowed_packet MySQL setting.';
+$string['dbsessionhandlerproblem'] = 'Setting up of database session failed. Please notify the server administrator.';
+$string['dbsessionmysqlpacketsize'] = 'A serious session error was detected. Please notify the site administrator. The problem is most probably caused by small value in max_allowed_packet MySQL setting.';
 $string['dbupdatefailed'] = 'Database update failed';
 $string['ddldependencyerror'] = '{$a->targettype} "{$a->targetname}" cannot be modified. Dependency found with {$a->offendingtype} "{$a->offendingname}"';
 $string['ddlexecuteerror'] = 'DDL sql execution error';
@@ -451,7 +451,8 @@ $string['querystringcannotbeempty'] = 'The query string cannot be empty.';
 $string['redirecterrordetected'] = 'Unsupported redirect detected, script execution terminated';
 $string['refoundto'] = 'Can be refunded to {$a}';
 $string['refoundtoorigi'] = 'Refunded to original amount: {$a}';
-$string['remotedownloaderror'] = 'Download of component to your server failed, please verify proxy settings, PHP cURL extension is highly recommended.<br /><br />You must download the <a href="{$a->url}">{$a->url}</a> file manually, copy it to "{$a->dest}" in your server and unzip it there.';
+$string['remotedownloaderror'] = '<p>The download of the component to your server failed. Please verify proxy settings; the PHP cURL extension is highly recommended.</p>
+<p>You must download the <a href="{$a->url}">{$a->url}</a> file manually, copy it to "{$a->dest}" in your server and unzip it there.</p>';
 $string['remotedownloadnotallowed'] = 'Download of components to your server isn\'t allowed (allow_url_fopen is disabled).<br /><br />You must download the <a href="{$a->url}">{$a->url}</a> file manually, copy it to "{$a->dest}" in your server and unzip it there.';
 $string['reportnotavailable'] = 'This type of report is only available for the site course';
 $string['requirecorrectaccess'] = 'Invalid url or port.';
@@ -470,12 +471,13 @@ $string['serverconnection'] = 'Error connecting to the server';
 $string['servicedonotexist'] = 'The service does not exist';
 $string['sessionwaiterr'] = 'Timed out while waiting for session lock.<br />Wait for your current requests to finish and try again later.';
 $string['sessioncookiesdisable'] = 'Incorrect use of require_key_login() - session cookies must be disabled!';
-$string['sessiondiskfull'] = 'The session partition is full. It is not possible to login at this time.<br /><br />Please notify server administrator.';
+$string['sessiondiskfull'] = 'The session partition is full. It is not possible to login at this time. Please notify the server administrator.';
 $string['sessionhandlerproblem'] = 'Session handler is misconfigured';
 $string['sessionerroruser'] = 'Your session has timed out.  Please login again.';
 $string['sessionerroruser2'] = 'A server error that affects your login session was detected. Please login again or restart your browser.';
 $string['sessionipnomatch'] = 'Sorry, but your IP number seems to have changed from when you first logged in.  This security feature prevents crackers stealing your identity while logged in to this site.  Normal users should not be seeing this message - please ask the site administrator for help.';
-$string['sessionipnomatch2'] = 'Sorry, but your IP number seems to have changed from when you first logged in.  This security feature prevents crackers stealing your identity while logged in to this site. You may see this error if you use wireless networks or if you are roaming between different networks. Please ask the site administrator for more help.<br /><br />If you want to continue please press F5 key to refresh this page.';
+$string['sessionipnomatch2'] = '<p>Sorry, but your IP number seems to have changed from when you first logged in. This security feature prevents crackers stealing your identity while logged in to this site. You may see this error if you use wireless networks or if you are roaming between different networks. Please ask the site administrator for more help.</p>
+<p>If you want to continue please press F5 key to refresh this page.</p>';
 $string['shortnametaken'] = 'Short name is already used for another course ({$a})';
 $string['scheduledbackupsdisabled'] = 'Scheduled backups have been disabled by the server admin';
 $string['socksnotsupported'] = 'SOCKS5 proxy is not supported in PHP4';
index 3be622d..589efa5 100644 (file)
@@ -61,10 +61,10 @@ $string['nosharedformfound'] = 'No template found';
 $string['searchtemplate'] = 'Grading forms search';
 $string['searchtemplate_help'] = 'You can search for a grading form and use it as a template for the new grading form here. Simply type words that should appear somewhere in the form name, its description or the form body itself. To search for a phrase, wrap the whole query in double quotes.
 
-By default, only the grading forms that have been saved as shared templates are included in the search results. You can also include all your own grading forms in the search results. This way, you can simply re-use your grading forms without sharing them. Only forms marked as \'Ready for usage\' can be re-used this way.';
+By default, only the grading forms that have been saved as shared templates are included in the search results. You can also include all your own grading forms in the search results. This way, you can simply re-use your grading forms without sharing them. Only forms marked as \'Ready for use\' can be re-used this way.';
 $string['searchownforms'] = 'include my own forms';
 $string['statusdraft'] = 'Draft';
-$string['statusready'] = 'Ready for usage';
+$string['statusready'] = 'Ready for use';
 $string['templatedelete'] = 'Delete';
 $string['templatedeleteconfirm'] = 'You are going to delete the shared template \'{$a}\'. Deleting a template does not affect existing forms that were created from it.';
 $string['templateedit'] = 'Edit';
index beaab45..715634e 100644 (file)
@@ -58,7 +58,9 @@ $string['deleteselectedgroup'] = 'Delete selected group';
 $string['editgroupingsettings'] = 'Edit grouping settings';
 $string['editgroupsettings'] = 'Edit group settings';
 $string['enrolmentkey'] = 'Enrolment key';
-$string['enrolmentkey_help'] = 'An enrolment key enables access to the course to be restricted to only those who know the key. If a group enrolment key is specified, then not only will entering that key let the user into the course, but it will also automatically make them a member of this group.';
+$string['enrolmentkey_help'] = 'An enrolment key enables access to the course to be restricted to only those who know the key. If a group enrolment key is specified, then not only will entering that key let the user into the course, but it will also automatically make them a member of this group.
+
+Note: Group enrolment keys must be enabled in the self enrolment settings and an enrolment key for the course must also be specified.';
 $string['erroraddremoveuser'] = 'Error adding/removing user {$a} to group';
 $string['erroreditgroup'] = 'Error creating/updating group {$a}';
 $string['erroreditgrouping'] = 'Error creating/updating grouping {$a}';
index 0f537a4..da2502e 100644 (file)
@@ -1573,7 +1573,12 @@ $string['searchagain'] = 'Search again';
 $string['searchbyemail'] = 'Search by email address';
 $string['searchbyusername'] = 'Search by username';
 $string['searchcourses'] = 'Search courses';
-$string['searchhelp'] = 'You can search for multiple words at once.<br /><br />word : find any match of this word within the text.<br />+word : only exact matching words will be found.<br />-word : don\'t include results containing this word.';
+$string['searchhelp'] = '<p>You can search for multiple words at once and can refine your search as follows:</p>
+<ul>
+<li>word - find any match of this word within the text.</li>
+<li>+word - only exact matching words will be found.</li>
+<li>-word - don\'t include results containing this word.</li>
+</ul>';
 $string['searchoptions'] = 'Search options';
 $string['searchresults'] = 'Search results';
 $string['sec'] = 'sec';
@@ -1614,7 +1619,7 @@ $string['selectmoduletoviewhelp'] = 'Select an activity or resource to view its
 Double-click on an activity or resource name to quickly add it.';
 $string['selectnos'] = 'Select all \'No\'';
 $string['selectperiod'] = 'Select period';
-$string['selectcategorysort'] = 'Which categories would you like to sort';
+$string['selectcategorysort'] = 'Which categories would you like to sort?';
 $string['selectcategorysortby'] = 'Select how you would like to sort categories';
 $string['selectcoursesortby'] = 'Select how you would like to sort courses';
 $string['senddetails'] = 'Send my details via email';
index 27b569d..092e50f 100644 (file)
@@ -92,7 +92,8 @@ $string['defaultinfofor'] = 'The default category for questions shared in contex
 $string['defaultmarkmustbepositive'] = 'The default mark must be positive.';
 $string['deletecoursecategorywithquestions'] = 'There are questions in the question bank associated with this course category. If you proceed, they will be deleted. You may wish to move them first, using the question bank interface.';
 $string['deletequestioncheck'] = 'Are you absolutely sure you want to delete \'{$a}\'?';
-$string['deletequestionscheck'] = 'Are you absolutely sure you want to delete the following questions?<br /><br />{$a}';
+$string['deletequestionscheck'] = '<p>Are you absolutely sure you want to delete the following questions?</p>
+<p>{$a}</p>';
 $string['deletingbehaviour'] = 'Deleting question behaviour \'{$a}\'';
 $string['deletingqtype'] = 'Deleting question type \'{$a}\'';
 $string['didnotmatchanyanswer'] = '[Did not match any answer]';
index dcbb81b..b089dfa 100644 (file)
@@ -124,7 +124,7 @@ $string['course:activityvisibility'] = 'Hide/show activities';
 $string['course:bulkmessaging'] = 'Send a message to many people';
 $string['course:create'] = 'Create courses';
 $string['course:delete'] = 'Delete courses';
-$string['course:viewsuspendedusers'] = 'Can view suspended users.';
+$string['course:viewsuspendedusers'] = 'View suspended users';
 $string['course:changecategory'] = 'Change course category';
 $string['course:changefullname'] = 'Change course full name';
 $string['course:changeidnumber'] = 'Change course ID number';
@@ -394,8 +394,8 @@ $string['user:manageblocks'] = 'Manage blocks on user profile of other users';
 $string['user:manageownblocks'] = 'Manage blocks on own public user profile';
 $string['user:manageownfiles'] = 'Manage files on own private file areas';
 $string['user:managesyspages'] = 'Configure default page layout for public user profiles';
-$string['user:readuserblogs'] = 'See all user blogs';
-$string['user:readuserposts'] = 'See all user posts';
+$string['user:readuserblogs'] = 'View all user blogs';
+$string['user:readuserposts'] = 'View all user forum posts';
 $string['user:update'] = 'Update user profiles';
 $string['user:viewalldetails'] = 'View user full information';
 $string['user:viewdetails'] = 'View user profiles';
index 52966b2..90c8d9e 100644 (file)
@@ -52,7 +52,7 @@ $string['createtokenforuser'] = 'Create a token for a user';
 $string['createtokenforuserdescription'] = 'Create a token for the web services user.';
 $string['createuser'] = 'Create a specific user';
 $string['createuserdescription'] = 'A web services user is required to represent the system controlling Moodle.';
-$string['criteriaerror'] = 'Missing permissions to search on a criteria.';
+$string['criteriaerror'] = 'Missing permissions to search on a criterion.';
 $string['default'] = 'Default to "{$a}"';
 $string['deleteaservice'] = 'Delete service';
 $string['deleteservice'] = 'Delete the service: {$a->name} (id: {$a->id})';
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?");
+    }
 }
 
 /**
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 0f0ff8d..398c98d 100644 (file)
 
 $string['allowattachments'] = 'Allow attachments';
 $string['allowusermailcharset'] = 'Allow user to select character set';
-$string['configallowattachments'] = 'Enabling this setting will allow file attachments to be sent with email messages generated by various features across the site, such as blogs, forums, or badges';
-$string['configallowusermailcharset'] = 'Enabling this, every user in the site will be able to specify his own charset for email.';
+$string['configallowattachments'] = 'If enabled, emails sent from the site can have attachments, such as badges.';
+$string['configallowusermailcharset'] = 'If enabled, users can choose an email charset in their profile settings.';
 $string['configmailnewline'] = 'Newline characters used in mail messages. CRLF is required according to RFC 822bis, some mail servers do automatic conversion from LF to CRLF, other mail servers do incorrect conversion from CRLF to CRCRLF, yet others reject mails with bare LF (qmail for example). Try changing this setting if you are having problems with undelivered emails or double newlines.';
 $string['confignoreplyaddress'] = 'Emails are sometimes sent out on behalf of a user (eg forum posts). The email address you specify here will be used as the "From" address in those cases when the recipients should not be able to reply directly to the user (eg when a user chooses to keep their address private).';
-$string['configsitemailcharset'] = 'All the emails generated by your site will be sent in the charset specified here. Anyway, every individual user will be able to adjust it if the next setting is enabled.';
+$string['configsitemailcharset'] = 'This setting specifies the default charset for all emails sent from the site.';
 $string['configsmtphosts'] = 'Give the full name of one or more local SMTP servers that Moodle should use to send mail (eg \'mail.a.com\' or \'mail.a.com;mail.b.com\'). To specify a non-default port (i.e other than port 25), you can use the [server]:[port] syntax (eg \'mail.a.com:587\'). For secure connections, port 465 is usually used with SSL, port 587 is usually used with TLS, specify security protocol below if required. If you leave this field blank, Moodle will use the PHP default method of sending mail.';
 $string['configsmtpmaxbulk'] = 'Maximum number of messages sent per SMTP session. Grouping messages may speed up the sending of emails. Values lower than 2 force creation of new SMTP session for each email.';
-$string['configsmtpsecure'] = 'If smtp server requires secure connection, specify the correct protocol type.';
+$string['configsmtpsecure'] = 'If SMTP server requires secure connection, specify the correct protocol type.';
 $string['configsmtpuser'] = 'If you have specified an SMTP server above, and the server requires authentication, then enter the username and password here.';
 $string['email'] = 'Send email notifications to';
 $string['ifemailleftempty'] = 'Leave empty to send notifications to {$a}';
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 916df63..b677b20 100644 (file)
@@ -61,9 +61,9 @@ assignment submission for \'{$a->assignment}\'
 You can see it appended to your assignment submission:
 
     {$a->url}';
-$string['assignmentmailhtml'] = '{$a->grader} has posted some feedback on your
-assignment submission for \'<i>{$a->assignment}</i>\'<br /><br />
-You can see it appended to your <a href="{$a->url}">assignment submission</a>.';
+$string['assignmentmailhtml'] = '<p>{$a->grader} 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->grader} has posted some feedback on your
 assignment submission for \'{$a->assignment}\' You can see it appended to your submission';
 $string['assignmentname'] = 'Assignment name';
@@ -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...';
@@ -334,9 +338,9 @@ assignment submission for \'{$a->assignment}\'
 You can see the status of your assignment submission:
 
     {$a->url}';
-$string['submissioncopiedhtml'] = 'You have made a copy of your previous
-assignment submission for \'<i>{$a->assignment}</i>\'<br /><br />
-You can see the status of your <a href="{$a->url}">assignment submission</a>.';
+$string['submissioncopiedhtml'] = '<p>You have made a copy of your previous
+assignment submission for \'<i>{$a->assignment}</i>\'.</p>
+<p>You can see the status of your <a href="{$a->url}">assignment submission</a>.</p>';
 $string['submissioncopiedsmall'] = 'You have copied your previous assignment submission for {$a->assignment}';
 $string['submissiondrafts'] = 'Require students click submit button';
 $string['submissiondrafts_help'] = 'If enabled, students will have to click a Submit button to declare their submission as final. This allows students to keep a draft version of the submission on the system. If this setting is changed from "No" to "Yes" after students have already submitted those submissions will be regarded as final.';
@@ -352,9 +356,8 @@ assignment submission for \'{$a->assignment}\'
 You can see the status of your assignment submission:
 
     {$a->url}';
-$string['submissionreceipthtml'] = 'You have submitted an
-assignment submission for \'<i>{$a->assignment}</i>\'<br /><br />
-You can see the status of your <a href="{$a->url}">assignment submission</a>.';
+$string['submissionreceipthtml'] = '<p>You have submitted an assignment submission for \'<i>{$a->assignment}</i>\'.</p>
+<p>You can see the status of your <a href="{$a->url}">assignment submission</a>.</p>';
 $string['submissionreceiptsmall'] = 'You have submitted your assignment submission for {$a->assignment}';
 $string['submissionslocked'] = 'This assignment is not accepting submissions';
 $string['submissionslockedshort'] = 'Submission changes not allowed';
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 29c37fa..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'] = '{$a->teacher} has posted some feedback on your
-assignment submission for \'<i>{$a->assignment}</i>\'<br /><br />
-You can see it appended to your <a href="{$a->url}">assignment submission</a>.';
-$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'] = '{$a->username} has updated their assignment submission
-for <i>\'{$a->assignment}\'  at {$a->timeupdated}</i><br /><br />
-It is <a href="{$a->url}">available on the web site</a>.';
-$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));
-        re