Merge branch 'MDL-51925-master' of git://github.com/jleyva/moodle
authorDan Poltawski <dan@moodle.com>
Tue, 1 Dec 2015 09:47:36 +0000 (09:47 +0000)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Thu, 3 Dec 2015 10:11:03 +0000 (11:11 +0100)
236 files changed:
.travis.yml
admin/settings/plugins.php
admin/settings/subsystems.php
admin/tool/availabilityconditions/tests/behat/manage_conditions.feature
admin/tool/customlang/db/upgrade.php
admin/tool/log/db/upgrade.php
admin/tool/log/store/database/db/upgrade.php
admin/tool/log/store/standard/db/upgrade.php
admin/tool/monitor/db/upgrade.php
auth/cas/db/upgrade.php
auth/db/tests/db_test.php
auth/ldap/db/upgrade.php
auth/manual/db/upgrade.php
auth/mnet/db/upgrade.php
availability/condition/completion/tests/behat/availability_completion.feature
availability/condition/completion/tests/behat/conditional_bug.feature
availability/condition/date/tests/behat/availability_date.feature
availability/condition/grade/tests/behat/availability_grade.feature
availability/condition/group/tests/behat/availability_group.feature
availability/condition/grouping/tests/behat/availability_grouping.feature
availability/condition/profile/tests/behat/availability_profile.feature
availability/tests/behat/display_availability.feature
availability/tests/behat/edit_availability.feature
availability/tests/info_test.php
backup/backup.class.php
badges/tests/behat/award_badge.feature
blocks/badges/db/upgrade.php
blocks/calendar_month/db/upgrade.php
blocks/calendar_upcoming/db/upgrade.php
blocks/community/db/upgrade.php
blocks/completionstatus/db/upgrade.php
blocks/course_summary/db/upgrade.php
blocks/html/db/upgrade.php
blocks/navigation/db/upgrade.php
blocks/quiz_results/db/upgrade.php
blocks/recent_activity/db/upgrade.php
blocks/recent_activity/tests/behat/structural_changes.feature
blocks/rss_client/db/upgrade.php
blocks/section_links/db/upgrade.php
blocks/selfcompletion/db/upgrade.php
blocks/settings/db/upgrade.php
blog/edit.php
blog/index.php
blog/tests/behat/delete.feature [new file with mode: 0644]
completion/tests/behat/enable_manual_complete_mark.feature
completion/tests/behat/restrict_activity_by_date.feature
completion/tests/behat/restrict_activity_by_grade.feature
completion/tests/behat/restrict_section_availability.feature
completion/tests/behat/teacher_manual_completion.feature
course/tests/behat/activities_edit_completion.feature
course/tests/externallib_test.php
enrol/database/db/upgrade.php
enrol/flatfile/db/upgrade.php
enrol/guest/db/upgrade.php
enrol/imsenterprise/db/upgrade.php
enrol/manual/db/upgrade.php
enrol/mnet/db/upgrade.php
enrol/paypal/db/upgrade.php
enrol/self/db/upgrade.php
filter/mathjaxloader/db/upgrade.php
filter/mediaplugin/db/upgrade.php
filter/tex/db/upgrade.php
grade/grading/form/rubric/db/upgrade.php
grade/report/overview/index.php
grade/report/singleview/classes/local/ui/dropdown_attribute.php
grade/report/singleview/classes/local/ui/text_attribute.php
grade/report/singleview/js/singleview.js
grade/report/user/db/upgrade.php
install/css.php
install/lang/cs/install.php
install/lang/cs/moodle.php
install/lang/eu/moodle.php
install/lang/fr/moodle.php
install/lang/hu/moodle.php
install/lang/it/moodle.php
install/lang/no/moodle.php
install/lang/ro/admin.php
install/lang/zh_cn/admin.php
install/lang/zh_tw/moodle.php
lang/en/admin.php
lang/en/blog.php
lang/en/cache.php
lang/en/edufields.php
lang/en/grades.php
lang/en/hub.php
lang/en/moodle.php
lang/en/plagiarism.php
lang/en/repository.php
lib/amd/build/form-autocomplete.min.js
lib/amd/src/form-autocomplete.js
lib/behat/classes/behat_context_helper.php
lib/behat/classes/behat_selectors.php
lib/classes/plugininfo/calendartype.php
lib/classes/useragent.php
lib/db/services.php
lib/db/upgrade.php
lib/deprecatedlib.php
lib/editor/atto/db/upgrade.php
lib/editor/atto/plugins/equation/db/upgrade.php
lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin-debug.js
lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin-min.js
lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin.js
lib/editor/atto/yui/src/editor/meta/editor.json
lib/editor/tinymce/db/upgrade.php
lib/editor/tinymce/plugins/spellchecker/db/upgrade.php
lib/enrollib.php
lib/filterlib.php
lib/flowplayer/lib.php
lib/moodlelib.php
lib/navigationlib.php
lib/outputrenderers.php
lib/password_compat/readme_moodle.txt
lib/password_compat/tests/PasswordHashTest.php
lib/phpunit/classes/util.php
lib/tablelib.php
lib/tests/behat/behat_hooks.php
lib/tests/useragent_test.php
lib/tests/weblib_test.php
lib/upgrade.txt
lib/weblib.php
message/externallib.php
message/output/email/db/upgrade.php
message/output/jabber/db/upgrade.php
message/output/popup/db/upgrade.php
message/tests/externallib_test.php
mod/assign/db/upgrade.php
mod/assign/extensionform.php
mod/assign/feedback/comments/db/upgrade.php
mod/assign/feedback/editpdf/db/upgrade.php
mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-debug.js
mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-min.js
mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor.js
mod/assign/feedback/editpdf/yui/src/editor/js/annotation.js
mod/assign/feedback/editpdf/yui/src/editor/js/annotationstamp.js
mod/assign/feedback/editpdf/yui/src/editor/js/comment.js
mod/assign/feedback/editpdf/yui/src/editor/js/commentsearch.js
mod/assign/feedback/editpdf/yui/src/editor/js/drawable.js
mod/assign/feedback/editpdf/yui/src/editor/js/editor.js
mod/assign/feedback/editpdf/yui/src/editor/js/globals.js
mod/assign/feedback/file/db/upgrade.php
mod/assign/gradingtable.php
mod/assign/lang/en/assign.php
mod/assign/locallib.php
mod/assign/module.js
mod/assign/renderable.php
mod/assign/submission/comments/db/upgrade.php
mod/assign/submission/file/db/upgrade.php
mod/assign/submission/onlinetext/db/upgrade.php
mod/assign/tests/behat/grant_extension.feature
mod/assign/tests/locallib_test.php
mod/assign/view.php
mod/assignment/db/upgrade.php
mod/book/db/upgrade.php
mod/book/tests/behat/log_entries.feature
mod/chat/db/upgrade.php
mod/chat/lib.php
mod/choice/db/upgrade.php
mod/data/db/upgrade.php
mod/data/field/checkbox/field.class.php
mod/feedback/db/upgrade.php
mod/feedback/tests/behat/show_nonrespondents.feature
mod/folder/db/upgrade.php
mod/forum/db/upgrade.php
mod/forum/tests/behat/completion_condition_number_discussions.feature
mod/forum/tests/behat/forum_subscriptions_availability.feature
mod/glossary/db/upgrade.php
mod/imscp/db/upgrade.php
mod/label/db/upgrade.php
mod/lesson/db/upgrade.php
mod/lesson/tests/behat/completion_condition_end_reached.feature
mod/lesson/tests/behat/completion_condition_time_spent.feature
mod/lti/db/upgrade.php
mod/page/db/upgrade.php
mod/quiz/db/upgrade.php
mod/quiz/report/overview/db/upgrade.php
mod/quiz/report/statistics/db/upgrade.php
mod/quiz/tests/behat/attempt_redo_questions.feature
mod/quiz/tests/behat/completion_condition_attempts_used.feature
mod/quiz/tests/behat/completion_condition_passing_grade.feature
mod/resource/db/upgrade.php
mod/scorm/db/upgrade.php
mod/survey/db/upgrade.php
mod/url/db/upgrade.php
mod/wiki/db/upgrade.php
mod/workshop/db/upgrade.php
mod/workshop/form/accumulative/db/upgrade.php
mod/workshop/form/comments/db/upgrade.php
mod/workshop/form/numerrors/db/upgrade.php
mod/workshop/form/rubric/db/upgrade.php
notes/tests/behat/participants_notes.feature [new file with mode: 0644]
portfolio/boxnet/db/upgrade.php
portfolio/googledocs/db/upgrade.php
portfolio/picasa/db/upgrade.php
question/behaviour/manualgraded/db/upgrade.php
question/type/calculated/db/upgrade.php
question/type/ddimageortext/tests/behat/preview.feature
question/type/ddmarker/db/upgrade.php
question/type/ddmarker/tests/behat/preview.feature
question/type/essay/db/upgrade.php
question/type/match/db/upgrade.php
question/type/multianswer/db/upgrade.php
question/type/multichoice/db/upgrade.php
question/type/numerical/db/upgrade.php
question/type/random/db/upgrade.php
question/type/randomsamatch/db/upgrade.php
question/type/shortanswer/db/upgrade.php
report/completion/styles.css
report/participation/index.php
report/participation/tests/behat/message_participants.feature [new file with mode: 0644]
report/progress/styles.css
repository/alfresco/db/upgrade.php
repository/boxnet/db/upgrade.php
repository/dropbox/db/upgrade.php
repository/googledocs/db/upgrade.php
repository/picasa/db/upgrade.php
theme/bootstrapbase/less/moodle/modules.less
theme/bootstrapbase/style/moodle.css
theme/clean/classes/core_renderer.php
theme/clean/lang/en/theme_clean.php
theme/clean/layout/columns1.php
theme/clean/layout/columns2.php
theme/clean/layout/columns3.php
theme/clean/layout/secure.php
theme/clean/lib.php
theme/clean/settings.php
theme/clean/style/custom.css
theme/clean/version.php
theme/more/db/upgrade.php
theme/more/lang/en/theme_more.php
theme/more/lib.php
theme/more/settings.php
theme/more/style/custom.css
theme/more/version.php
theme/upgrade.txt
user/addnote.php
version.php

index 9deb770..c462b85 100644 (file)
@@ -191,14 +191,6 @@ script:
         export phpcmd=`which php`;
       fi
 
-    - >
-      if [ "$CITEST" = "true" -a "$GIT_PREVIOUS_COMMIT" != "$UPSTREAM_FETCH_HEAD" ];
-      then
-        # This is a CI test, but it is based on an older weekly release.
-        # Warn in a way that will fail the test.
-        echo "Current commit is based on an older weekly release" && false;
-      fi
-
     # Actually run the CI Tests - do this outside of the main test to make output clearer.
     - >
       if [ "$CITEST" = 'true' ];
index f5ea9e3..9ed5af8 100644 (file)
@@ -489,10 +489,9 @@ if ($hassiteconfig) {
 // Add Calendar type settings.
 if ($hassiteconfig) {
     $ADMIN->add('modules', new admin_category('calendartype', new lang_string('calendartypes', 'calendar')));
-    foreach (core_component::get_plugin_list_with_file('calendartype', 'settings.php') as $plugin => $settingspath) {
-        $settings = new admin_settingpage('calendartype_' . $plugin . '_settings', new lang_string('pluginname', 'calendartype_' . $plugin), 'moodle/site:config');
-        include($settingspath);
-        $ADMIN->add('calendartype', $settings);
+    foreach (core_plugin_manager::instance()->get_plugins_of_type('calendartype') as $plugin) {
+        /** @var \core\plugininfo\calendartype $plugin */
+        $plugin->load_settings($ADMIN, 'calendartype', $hassiteconfig);
     }
 }
 
index 1eae0d0..9cae26c 100644 (file)
@@ -34,7 +34,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
     // Conditional activities: completion and availability
     $optionalsubsystems->add(new admin_setting_configcheckbox('enablecompletion',
         new lang_string('enablecompletion','completion'),
-        new lang_string('configenablecompletion','completion'), 0));
+        new lang_string('configenablecompletion', 'completion'), 1));
 
     $options = array(
         1 => get_string('completionactivitydefault', 'completion'),
@@ -45,7 +45,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
 
     $optionalsubsystems->add($checkbox = new admin_setting_configcheckbox('enableavailability',
             new lang_string('enableavailability', 'availability'),
-            new lang_string('enableavailability_desc', 'availability'), 0));
+            new lang_string('enableavailability_desc', 'availability'), 1));
     $checkbox->set_affects_modinfo(true);
 
     $optionalsubsystems->add(new admin_setting_configcheckbox('enableplagiarism', new lang_string('enableplagiarism','plagiarism'), new lang_string('configenableplagiarism','plagiarism'), 0));
index 9234fee..65b0b4a 100644 (file)
@@ -8,6 +8,8 @@ Feature: Manage availability conditions
   Scenario: Display list of availability conditions
     # Check the report doesn't show when not enabled.
     Given I log in as "admin"
+    And the following config values are set as admin:
+      | enableavailability | 0 |
     And I expand "Site administration" node
     When I expand "Plugins" node
     Then I should not see "Availability restrictions"
@@ -28,8 +30,6 @@ Feature: Manage availability conditions
     Given the following "courses" exist:
       | fullname | shortname | format |
       | Course 1 | C1        | topics |
-    And the following config values are set as admin:
-      | enableavailability | 1 |
     And I log in as "admin"
     And I am on site homepage
     When I navigate to "Manage restrictions" node in "Site administration > Plugins > Availability restrictions"
index 489f887..01f87e9 100644 (file)
@@ -54,5 +54,8 @@ function xmldb_tool_customlang_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index da2a60c..2a4eab3 100644 (file)
@@ -52,5 +52,8 @@ function xmldb_tool_log_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index f12d844..565efed 100644 (file)
@@ -42,5 +42,8 @@ function xmldb_logstore_database_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 0fa6a8f..9b4247b 100644 (file)
@@ -120,5 +120,8 @@ function xmldb_logstore_standard_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index ffb1750..f02556d 100644 (file)
@@ -56,5 +56,8 @@ function xmldb_tool_monitor_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index f3abc34..bca88a4 100644 (file)
@@ -74,5 +74,8 @@ function xmldb_auth_cas_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index e619df6..7979bd8 100644 (file)
@@ -309,7 +309,7 @@ class auth_db_testcase extends advanced_testcase {
         require_once($CFG->libdir.'/password_compat/lib/password.php');
         set_config('passtype', 'saltedcrypt', 'auth/db');
         $auth->config->passtype = 'saltedcrypt';
-        $user3->pass = password_hash('heslo', PASSWORD_BCRYPT, array('salt' => 'best_salt_ever_moodle_rocks_dont_tell'));
+        $user3->pass = password_hash('heslo', PASSWORD_BCRYPT);
         $DB->update_record('auth_db_users', $user3);
         $this->assertTrue($auth->user_login('u3', 'heslo'));
 
index e73f929..3a320e3 100644 (file)
@@ -64,5 +64,8 @@ function xmldb_auth_ldap_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index e306b6a..3039953 100644 (file)
@@ -56,5 +56,8 @@ function xmldb_auth_manual_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 5d2cb16..0090939 100644 (file)
@@ -56,5 +56,8 @@ function xmldb_auth_mnet_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 3d95470..507ba1b 100644 (file)
@@ -16,9 +16,6 @@ Feature: availability_completion
       | user     | course | role           |
       | teacher1 | C1     | editingteacher |
       | student1 | C1     | student        |
-    And the following config values are set as admin:
-      | enableavailability  | 1 |
-      | enablecompletion | 1 |
 
   @javascript
   Scenario: Test condition
index b7f6fec..402afdd 100644 (file)
@@ -14,9 +14,6 @@ Feature: Confirm that conditions on completion no longer cause a bug
     And the following "course enrolments" exist:
       | user     | course | role           |
       | teacher1 | C1     | editingteacher |
-    And the following config values are set as admin:
-      | enableavailability | 1 |
-      | enablecompletion   | 1 |
 
   @javascript
   Scenario: Multiple completion conditions on glossary
index 925781d..161080f 100644 (file)
@@ -16,8 +16,6 @@ Feature: availability_date
       | user     | course | role           |
       | teacher1 | C1     | editingteacher |
       | student1 | C1     | student        |
-    And the following config values are set as admin:
-      | enableavailability  | 1 |
 
   @javascript
   Scenario: Test condition
index 967e7c8..9c250e1 100644 (file)
@@ -16,8 +16,6 @@ Feature: availability_grade
       | user     | course | role           |
       | teacher1 | C1     | editingteacher |
       | student1 | C1     | student        |
-    And the following config values are set as admin:
-      | enableavailability  | 1 |
 
   @javascript
   Scenario: Test condition
index d3c2b06..31d65d2 100644 (file)
@@ -16,8 +16,6 @@ Feature: availability_group
       | user     | course | role           |
       | teacher1 | C1     | editingteacher |
       | student1 | C1     | student        |
-    And the following config values are set as admin:
-      | enableavailability  | 1 |
 
   @javascript
   Scenario: Test condition
index e33b588..3c1ccb1 100644 (file)
@@ -22,8 +22,6 @@ Feature: availability_grouping
     And the following "group members" exist:
       | user     | group |
       | student1 | GI1   |
-    And the following config values are set as admin:
-      | enableavailability  | 1 |
 
   @javascript
   Scenario: Test condition
index ba207a1..2222fb7 100644 (file)
@@ -16,8 +16,6 @@ Feature: availability_profile
       | user     | course | role           |
       | teacher1 | C1     | editingteacher |
       | student1 | C1     | student        |
-    And the following config values are set as admin:
-      | enableavailability  | 1 |
 
   @javascript
   Scenario: Test condition
index ea70a05..0daeee2 100644 (file)
@@ -34,8 +34,6 @@ Feature: display_availability
       | user     | course | role           |
       | teacher1 | C1     | editingteacher |
       | student1 | C1     | student        |
-    And the following config values are set as admin:
-      | enableavailability | 1 |
 
   @javascript
   Scenario: Activity availability display
index 0af20b5..08a6f70 100644 (file)
@@ -29,6 +29,8 @@ Feature: edit_availability
       | student1 | C1     | student        |
 
   Scenario: Confirm the 'enable availability' option is working
+    Given the following config values are set as admin:
+      | enableavailability | 0 |
     When I log in as "teacher1"
     And I am on site homepage
     And I follow "Course 1"
@@ -55,9 +57,7 @@ Feature: edit_availability
   @javascript
   Scenario: Edit availability using settings in activity form
     # Set up.
-    Given the following config values are set as admin:
-      | enableavailability | 1 |
-    And I log in as "teacher1"
+    Given I log in as "teacher1"
     And I follow "Course 1"
 
     # Add a Page and check it has None in so far.
@@ -148,9 +148,7 @@ Feature: edit_availability
   @javascript
   Scenario: Edit availability using settings in section form
     # Set up.
-    Given the following config values are set as admin:
-      | enableavailability | 1 |
-    And I log in as "teacher1"
+    Given I log in as "teacher1"
     And I am on site homepage
     And I follow "Course 1"
     And I turn editing mode on
@@ -170,7 +168,9 @@ Feature: edit_availability
   @javascript
   Scenario: 'Add group/grouping access restriction' button unavailable
     # Button does not exist when conditional access restrictions are turned off.
-    Given I log in as "admin"
+    Given the following config values are set as admin:
+      | enableavailability | 0 |
+    And I log in as "admin"
     And I am on site homepage
     And I follow "Course 1"
     And I turn editing mode on
@@ -181,9 +181,7 @@ Feature: edit_availability
   @javascript
   Scenario: Use the 'Add group/grouping access restriction' button
     # Button should initially be disabled.
-    Given the following config values are set as admin:
-      | enableavailability | 1 |
-    And the following "groupings" exist:
+    Given the following "groupings" exist:
       | name | course | idnumber |
       | GX1  | C1     | GXI1     |
     And I log in as "admin"
index 1477978..d349b9c 100644 (file)
@@ -45,9 +45,10 @@ class info_testcase extends advanced_testcase {
      * Tests the info_module class (is_available, get_full_information).
      */
     public function test_info_module() {
-        global $DB;
+        global $DB, $CFG;
 
         // Create a course and pages.
+        $CFG->enableavailability = 0;
         $this->setAdminUser();
         $this->resetAfterTest();
         $generator = $this->getDataGenerator();
@@ -160,6 +161,7 @@ class info_testcase extends advanced_testcase {
         global $CFG, $DB;
         require_once($CFG->dirroot . '/course/lib.php');
         $this->resetAfterTest();
+        $CFG->enableavailability = 0;
 
         // Create a course and some pages:
         // 0. Invisible due to visible=0.
index 894aebd..0b2ed3f 100644 (file)
@@ -135,7 +135,7 @@ abstract class backup implements checksumable {
     /**
      * Usually same than major release zero version, mainly for informative/historic purposes.
      */
-    const RELEASE = '3.0';
+    const RELEASE = '3.1';
 }
 
 /*
index 4bb0a66..0b68bd7 100644 (file)
@@ -129,8 +129,6 @@ Feature: Award badges
       | user | course | role |
       | teacher1 | C1 | editingteacher |
       | student1 | C1 | student |
-    And the following config values are set as admin:
-      | enablecompletion | 1 |
     And I log in as "teacher1"
     And I follow "Course 1"
     And I follow "Edit settings"
@@ -180,8 +178,6 @@ Feature: Award badges
       | user | course | role |
       | teacher1 | C1 | editingteacher |
       | student1 | C1 | student |
-    And the following config values are set as admin:
-      | enablecompletion | 1 |
     And I log in as "teacher1"
     And I follow "Course 1"
     And I follow "Edit settings"
index 64c2e5d..a9ff3a1 100644 (file)
@@ -79,5 +79,8 @@ function xmldb_block_badges_upgrade($oldversion, $block) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 589c706..c83b12a 100644 (file)
@@ -79,5 +79,8 @@ function xmldb_block_calendar_month_upgrade($oldversion, $block) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index f3c8e4e..0836409 100644 (file)
@@ -79,5 +79,8 @@ function xmldb_block_calendar_upcoming_upgrade($oldversion, $block) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index c6002aa..bcc82dc 100644 (file)
@@ -69,5 +69,8 @@ function xmldb_block_community_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index bce3229..070ebcc 100644 (file)
@@ -76,5 +76,8 @@ function xmldb_block_completionstatus_upgrade($oldversion, $block) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
\ No newline at end of file
index b7c389a..0c1549e 100644 (file)
@@ -80,5 +80,8 @@ function xmldb_block_course_summary_upgrade($oldversion, $block) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
\ No newline at end of file
index 24776ae..ff87abf 100644 (file)
@@ -56,5 +56,8 @@ function xmldb_block_html_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 2f7240b..6ea9268 100644 (file)
@@ -81,5 +81,8 @@ function xmldb_block_navigation_upgrade($oldversion, $block) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
\ No newline at end of file
index d7edead..ec753c9 100644 (file)
@@ -104,5 +104,8 @@ function xmldb_block_quiz_results_upgrade($oldversion, $block) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
\ No newline at end of file
index 6a12a7a..8d0f893 100644 (file)
@@ -90,5 +90,8 @@ function xmldb_block_recent_activity_upgrade($oldversion, $block) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 4340c60..a43dbb7 100644 (file)
@@ -46,9 +46,7 @@ Feature: View structural changes in recent activity block
       | GG3      | G2    |
 
   Scenario: Check that Added module information is displayed respecting view capability
-    Given the following config values are set as admin:
-      | enableavailability | 1 |
-    And I log in as "teacher1"
+    Given I log in as "teacher1"
     And I follow "Course 1"
     And I turn editing mode on
     When I add a "Forum" to section "1" and I fill the form with:
index afc2b80..cf8294e 100644 (file)
@@ -50,5 +50,8 @@ function xmldb_block_rss_client_upgrade($oldversion) {
         upgrade_block_savepoint(true, 2015071700, 'rss_client');
     }
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 16d38de..057f275 100644 (file)
@@ -92,5 +92,8 @@ function xmldb_block_section_links_upgrade($oldversion, $block) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 79721a1..e79331c 100644 (file)
@@ -80,5 +80,8 @@ function xmldb_block_selfcompletion_upgrade($oldversion, $block) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
\ No newline at end of file
index 584ed9d..b1cf6f8 100644 (file)
@@ -81,5 +81,8 @@ function xmldb_block_settings_upgrade($oldversion, $block) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
\ No newline at end of file
index 7ff8333..14d4c87 100644 (file)
@@ -141,14 +141,15 @@ if ($action === 'delete') {
         // Output edit mode title.
         echo $OUTPUT->heading($strblogs . ': ' . get_string('deleteentry', 'blog'), 2);
 
+        echo $OUTPUT->confirm(get_string('blogdeleteconfirm', 'blog', format_string($entry->subject)),
+                              new moodle_url('edit.php', $optionsyes),
+                              new moodle_url('index.php', $optionsno));
+
+        echo '<br />';
         // Output the entry.
         $entry->prepare_render();
         echo $output->render($entry);
 
-        echo '<br />';
-        echo $OUTPUT->confirm(get_string('blogdeleteconfirm', 'blog'),
-                              new moodle_url('edit.php', $optionsyes),
-                              new moodle_url('index.php', $optionsno));
         echo $OUTPUT->footer();
         die;
     }
index ddbdf45..56ab7eb 100644 (file)
@@ -63,9 +63,9 @@ if ($entryid and !isset($userid)) {
     $userid = $entry->userid;
 }
 
-if (isset($userid) && !isset($courseid)) {
+if (isset($userid) && empty($courseid)) {
     $context = context_user::instance($userid);
-} else if (isset($courseid) && $courseid != SITEID) {
+} else if (!empty($courseid) && $courseid != SITEID) {
     $context = context_course::instance($courseid);
 } else {
     $context = context_system::instance();
diff --git a/blog/tests/behat/delete.feature b/blog/tests/behat/delete.feature
new file mode 100644 (file)
index 0000000..cd1dd5b
--- /dev/null
@@ -0,0 +1,43 @@
+@core @core_blog
+Feature: Delete a blog entry
+  In order to manage my blog entries
+  As a user
+  I need to be able to delete entries I no longer wish to appear
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email |
+      | testuser | Test | User | moodle@example.com |
+    And I log in as "testuser"
+    And I expand "Site pages" node
+    And I follow "Site blogs"
+    And I follow "Add a new entry"
+    And I set the following fields to these values:
+      | Entry title | Blog post one |
+      | Blog entry body | User 1 blog post content |
+    And I press "Save changes"
+    And I follow "Add a new entry"
+    And I set the following fields to these values:
+      | Entry title | Blog post two |
+      | Blog entry body | User 1 blog post content |
+    And I press "Save changes"
+    And I am on site homepage
+    And I expand "Site pages" node
+    And I follow "Site blogs"
+
+  Scenario: Delete blog post results in post deleted
+    Given I follow "Blog post one"
+    And I follow "Delete"
+    And I should see "Delete the blog entry 'Blog post one'?"
+    When I press "Continue"
+    Then I should not see "Blog post one"
+    And I should see "Blog post two"
+
+  Scenario: Delete confirmation screen works and allows cancel
+    Given I follow "Blog post one"
+    When I follow "Delete"
+    Then I should see "Delete the blog entry 'Blog post one'?"
+    And I press "Cancel"
+    And I should see "Blog post one"
+    And I should see "Blog post two"
+
index 93ba976..75a11a2 100644 (file)
@@ -17,9 +17,6 @@ Feature: Allow students to manually mark an activity as complete
       | user | course | role |
       | teacher1 | C1 | editingteacher |
       | student1 | C1 | student |
-    And the following config values are set as admin:
-      | enablecompletion | 1 |
-      | enableavailability | 1 |
     And I log in as "teacher1"
     And I am on site homepage
     And I follow "Course 1"
index fc3033d..5d19955 100644 (file)
@@ -16,8 +16,6 @@ Feature: Restrict activity availability through date conditions
       | user | course | role |
       | teacher1 | C1 | editingteacher |
       | student1 | C1 | student |
-    And the following config values are set as admin:
-      | enableavailability | 1 |
     And I log in as "teacher1"
     And I am on site homepage
     And I follow "Course 1"
index 3b0a60f..27fa423 100644 (file)
@@ -17,8 +17,6 @@ Feature: Restrict activity availability through grade conditions
       | user | course | role |
       | teacher1 | C1 | editingteacher |
       | student1 | C1 | student |
-    And the following config values are set as admin:
-      | enableavailability | 1 |
     And I log in as "teacher1"
     #And I am on site homepage
     And I follow "Course 1"
index 436c63d..3a74723 100644 (file)
@@ -16,9 +16,6 @@ Feature: Restrict sections availability through completion or grade conditions
       | user | course | role |
       | teacher1 | C1 | editingteacher |
       | student1 | C1 | student |
-    And the following config values are set as admin:
-      | enablecompletion   | 1 |
-      | enableavailability | 1 |
 
   @javascript
   Scenario: Show section greyed-out to student when completion condition is not satisfied
index 3b8c4d4..c1ce408 100644 (file)
@@ -16,11 +16,7 @@ Feature: Allow teachers to manually mark users as complete when configured
       | user     | course | role           |
       | student1 | CC1    | student        |
       | teacher1 | CC1    | editingteacher |
-    And the following config values are set as admin:
-      | enablecompletion | 1 |
     And I log in as "admin"
-    And I set the following administration settings values:
-      | Enable completion tracking | 1 |
     And I am on site homepage
     And I follow "Completion course"
     And completion tracking is "Enabled" in current course
index b264ea4..50878cc 100644 (file)
@@ -8,8 +8,6 @@ Feature: Edit completion settings of an activity
     Given the following "courses" exist:
       | fullname | shortname | enablecompletion |
       | Course 1 | C1        | 1                |
-    And the following config values are set as admin:
-      | enablecompletion | 1 |
     And I log in as "admin"
     And I am on site homepage
     And I follow "Course 1"
index e443b33..c5a6464 100644 (file)
@@ -1041,9 +1041,7 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
                     $this->assertEquals($course2['forcetheme'], $courseinfo->theme);
                 }
 
-                if (completion_info::is_enabled_for_site()) {
-                    $this->assertEquals($course2['enabledcompletion'], $courseinfo->enablecompletion);
-                }
+                $this->assertEquals($course2['enablecompletion'], $courseinfo->enablecompletion);
             } else if ($course['id'] == $course1['id']) {
                 $this->assertEquals($course1['fullname'], $courseinfo->fullname);
                 $this->assertEquals($course1['shortname'], $courseinfo->shortname);
index 450eaef..d1eb164 100644 (file)
@@ -53,5 +53,8 @@ function xmldb_enrol_database_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 8ad41f9..ebe5dd7 100644 (file)
@@ -54,5 +54,8 @@ function xmldb_enrol_flatfile_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index ccd51b1..8ae2004 100644 (file)
@@ -63,6 +63,9 @@ function xmldb_enrol_guest_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
 
index eb1f8ed..7fb9ea3 100644 (file)
@@ -56,5 +56,8 @@ function xmldb_enrol_imsenterprise_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index db7d182..7b98f19 100644 (file)
@@ -72,6 +72,9 @@ function xmldb_enrol_manual_upgrade($oldversion) {
         upgrade_plugin_savepoint(true, 2015091500, 'enrol', 'manual');
     }
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
 
index dea1555..e66d6ec 100644 (file)
@@ -55,5 +55,8 @@ function xmldb_enrol_mnet_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 01a1291..faf51dc 100644 (file)
@@ -70,5 +70,8 @@ function xmldb_enrol_paypal_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index eac4712..62cb0df 100644 (file)
@@ -71,6 +71,9 @@ function xmldb_enrol_self_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
 
index 68a9316..eb1e4cd 100644 (file)
@@ -109,5 +109,8 @@ MathJax.Hub.Config({
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index adfa7db..3e37445 100644 (file)
@@ -78,5 +78,8 @@ function xmldb_filter_mediaplugin_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index b08a9e5..703a7d4 100644 (file)
@@ -74,5 +74,8 @@ function xmldb_filter_tex_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 8194960..a40da47 100644 (file)
@@ -62,5 +62,8 @@ function xmldb_gradingform_rubric_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 15954dc..e46885c 100644 (file)
@@ -36,6 +36,7 @@ if (!$course = $DB->get_record('course', array('id' => $courseid))) {
     print_error('nocourseid');
 }
 require_login(null, false);
+$PAGE->set_course($course);
 
 $context = context_course::instance($course->id);
 $systemcontext = context_system::instance();
@@ -64,9 +65,9 @@ if (isset($personalcontext) && $courseid == SITEID) {
 if ($userid == $USER->id) {
     $settings = $PAGE->settingsnav->find('mygrades', null);
     $settings->make_active();
-} else if ($courseid != SITEID) {
+} else if ($courseid != SITEID && $userid) {
     // Show some other navbar thing.
-    $user = $DB->get_record('user', array('id' => $userid));
+    $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
     $PAGE->navigation->extend_for_user($user);
 }
 
index aaaed88..19bc80c 100644 (file)
@@ -83,7 +83,7 @@ class dropdown_attribute extends element {
             'value' => $this->selected
         );
 
-        $attributes = array();
+        $attributes = array('tabindex' => '1');
 
         if (!empty($this->isdisabled)) {
             $attributes['disabled'] = 'DISABLED';
index 2766a9d..0102199 100644 (file)
@@ -85,9 +85,11 @@ class text_attribute extends element {
         $label = '';
         if (preg_match("/^feedback/", $this->name)) {
             $labeltitle = get_string('feedbackfor', 'gradereport_singleview', $this->label);
+            $attributes['tabindex'] = '2';
             $label = html_writer::tag('label', $labeltitle,  array('for' => $this->name, 'class' => 'accesshide'));
         } else if (preg_match("/^finalgrade/", $this->name)) {
             $labeltitle = get_string('gradefor', 'gradereport_singleview', $this->label);
+            $attributes['tabindex'] = '1';
             $label = html_writer::tag('label', $labeltitle,  array('for' => $this->name, 'class' => 'accesshide'));
         }
 
index 0c377b8..7ee45eb 100644 (file)
@@ -1,6 +1,96 @@
 M.gradereport_singleview = {};
 
 M.gradereport_singleview.init = function(Y) {
+    var getColumnIndex = function(cell) {
+        var rowNode = cell.ancestor('tr');
+        if (!rowNode || !cell) {
+            return;
+        }
+        var cells = rowNode.all('td, th');
+        return cells.indexOf(cell);
+    },
+    getNextCell = function(cell) {
+        var n = cell || document.activeElement,
+            next = n.next('td.cell, th.cell');
+        if (!next) {
+            return null;
+        }
+        // Continue on until we find a navigable cell
+        if (!next || !Y.one(next).one('input:not([type="hidden"]):not([disabled="DISABLED"]), select, a')) {
+            return getNextCell(next);
+        }
+        return next;
+    },
+    getPrevCell = function(cell) {
+        var n = cell || document.activeElement,
+            next = n.previous('td.cell, th.cell');
+        if (!next) {
+            return null;
+        }
+        // Continue on until we find a navigable cell
+        if (!Y.one(next).one('input:not([type="hidden"]):not([disabled="DISABLED"]), select, a')) {
+            return getPrevCell(next);
+        }
+        return next;
+    },
+    getAboveCell = function(cell) {
+        var n = cell || document.activeElement,
+            tr = n.ancestor('tr').previous('tr'),
+            columnIndex = getColumnIndex(n),
+            next = null;
+        if (tr) {
+            next = tr.all('td, th').item(columnIndex);
+        } else {
+            return null;
+        }
+        // Continue on until we find a navigable cell
+        if (!Y.one(next).one('input:not([type="hidden"]):not([disabled="DISABLED"]), select, a')) {
+            return getAboveCell(next);
+        }
+        return next;
+    },
+    getBelowCell = function(cell) {
+        var n = cell || document.activeElement,
+            tr = n.ancestor('tr').next('tr'),
+            columnIndex = getColumnIndex(n),
+            next = null;
+        if (tr) {
+            next = tr.all('td, th').item(columnIndex);
+        } else {
+            return null;
+        }
+        // Continue on until we find a navigable cell
+        if (!Y.one(next).one('input:not([type="hidden"]):not([disabled="DISABLED"]), select, a')) {
+            return getBelowCell(next);
+        }
+        return next;
+    };
+
+    // Add ctrl+arrow controls for navigation
+    Y.one(Y.config.doc.body).delegate('key', function(e) {
+        e.preventDefault();
+        e.stopPropagation();
+        var next = null;
+        switch (e.keyCode) {
+            case 37:
+                next = getPrevCell(this.ancestor('td, th'));
+                break;
+            case 38:
+                next = getAboveCell(this.ancestor('td, th'));
+                break;
+            case 39:
+                next = getNextCell(this.ancestor('td, th'));
+                break;
+            case 40:
+                next = getBelowCell(this.ancestor('td, th'));
+                break;
+        }
+        if (next) {
+            Y.one(next).one('input:not([type="hidden"]):not([disabled="DISABLED"]), select, a').focus();
+        }
+        return;
+    }, 'down:37,38,39,40+ctrl', 'table input, table select, table a');
+
     // Make toggle links
     Y.all('.include').each(function(link) {
         var type = link.getAttribute('class').split(" ")[2];
index b4627ef..f79d0d1 100644 (file)
@@ -42,5 +42,8 @@ function xmldb_gradereport_user_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 0228dff..88c69fc 100644 (file)
@@ -33,7 +33,7 @@ if (file_exists(dirname(dirname(__FILE__)).'/config.php')) {
 // MDL-43839 IE9 cannot handle all of our css.
 // Once IE9 is no longer supported we can include 'bootstrapbase/style/moodle.css'
 // and remove some of the CSS in $content.
-$files = array('');
+$files = array();
 
 $content = '';
 
index fa05a34..3a79b41 100644 (file)
@@ -79,7 +79,7 @@ $string['phpversion'] = 'Verze PHP';
 $string['phpversionhelp'] = '<p>Moodle vyžaduje PHP alespoň verze 4.3.0 nebo 5.1.0 (PHP 5.0.x obsahuje množství chyb).</p>
 <p>Nyní používáte PHP verze {$a}.</p>
 <p>Musíte PHP upgradovat, nebo přejít k hostiteli s vyšší verzí!<br />
-(U PHP 5.0.x můžete také přejít na nižší verzi 4.4.x či 4.3.x.)</p>';
+(U PHP 5.0.x můžete také přejít na nižší verzi 4.4.x )</p>';
 $string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
 $string['welcomep20'] = 'Podařilo se vám úspěšně nainstalovat a spustit balíček <strong>{$a->packname} {$a->packversion}</strong>. Gratulujeme!';
 $string['welcomep30'] = '<strong>{$a->installername}</strong> obsahuje aplikace k vytvoření prostředí, ve kterém bude provozován váš <strong>Moodle</strong>. Jmenovitě se jedná o:';
index 102bae0..bccdf72 100644 (file)
@@ -31,6 +31,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $string['language'] = 'Jazyk';
+$string['moodlelogo'] = 'Moodle logo';
 $string['next'] = 'Další';
 $string['previous'] = 'Předchozí';
 $string['reload'] = 'Obnovit';
index b672e38..f483805 100644 (file)
@@ -31,6 +31,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $string['language'] = 'Hizkuntza';
+$string['moodlelogo'] = 'Moodle-ren logoa';
 $string['next'] = 'Hurrengoa';
 $string['previous'] = 'Aurrekoa';
 $string['reload'] = 'Berriz kargatu';
index 58e103c..e166cf8 100644 (file)
@@ -31,6 +31,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $string['language'] = 'Langue';
+$string['moodlelogo'] = 'Logo Moodle';
 $string['next'] = 'Suivant';
 $string['previous'] = 'Précédent';
 $string['reload'] = 'Actualiser';
index e3aa83c..57df885 100644 (file)
@@ -31,6 +31,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $string['language'] = 'Nyelv';
+$string['moodlelogo'] = 'Moodle-logó';
 $string['next'] = 'Következő';
 $string['previous'] = 'Előző';
 $string['reload'] = 'Újbóli betöltés';
index b831e82..afcef7b 100644 (file)
@@ -31,6 +31,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $string['language'] = 'Lingua';
+$string['moodlelogo'] = 'Logo Moodle';
 $string['next'] = 'Successivo';
 $string['previous'] = 'Precedente';
 $string['reload'] = 'Ricarica';
index 880f416..599fe50 100644 (file)
@@ -31,6 +31,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $string['language'] = 'Språk';
+$string['moodlelogo'] = 'Moodlelogo';
 $string['next'] = 'Neste';
 $string['previous'] = 'Forrige';
 $string['reload'] = 'Last på nytt';
index 8d1758c..6d15446 100644 (file)
@@ -42,3 +42,4 @@ Vă rugăm folosiţi --opţiunea Ajutor.';
 $string['cliyesnoprompt'] = 'introduceţi d (pentru \'da\') sau \'n\' (pentru \'nu\')';
 $string['environmentrequireinstall'] = 'trebuie instalat şi activat';
 $string['environmentrequireversion'] = 'versiuna necesară este {$a->needed} în timp ce dumneavoastră rulaţi versiunea {$a->current}';
+$string['upgradekeyset'] = 'Actualizează cheie  (lăsați gol pentru a nu fi setat)';
index d212e87..8f9c4a3 100644 (file)
@@ -42,3 +42,4 @@ $string['cliunknowoption'] = '未识别的选项:
 $string['cliyesnoprompt'] = '输入y(表示是)或n(表示否)';
 $string['environmentrequireinstall'] = '必须安装并启用';
 $string['environmentrequireversion'] = '需要 {$a->needed} 版本,而您的是 {$a->current}';
+$string['upgradekeyset'] = '升级密码(若不要设定请保持空白)';
index e8bc0f5..8b35289 100644 (file)
@@ -31,6 +31,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $string['language'] = '語言';
+$string['moodlelogo'] = 'Moodle 商標';
 $string['next'] = '往後';
 $string['previous'] = '向前';
 $string['reload'] = '重新載入';
index 390320b..1ecd467 100644 (file)
@@ -911,9 +911,9 @@ $string['requiredentrieschanged'] = '<strong>IMPORTANT - PLEASE READ<br/>(This w
 $string['requiremodintro'] = 'Require activity description';
 $string['requiremodintro_desc'] = 'If enabled, users will be forced to enter a description for each activity.';
 $string['requires'] = 'Requires';
-$string['purgecaches']= 'Purge all caches';
-$string['purgecachesconfirm']= 'Moodle can cache themes, javascript, language strings, filtered text, rss feeds and many other pieces of calculated data.  Purging these caches will delete that data from the server and force browsers to refetch data, so that you can be sure you are seeing the most up-to-date values produced by the current code.  There is no danger in purging caches, but your site may appear slower for a while until the server and clients calculate new information and cache it.';
-$string['purgecachesfinished']= 'All caches were purged.';
+$string['purgecaches'] = 'Purge all caches';
+$string['purgecachesconfirm'] = 'Moodle can cache themes, javascript, language strings, filtered text, rss feeds and many other pieces of calculated data.  Purging these caches will delete that data from the server and force browsers to refetch data, so that you can be sure you are seeing the most up-to-date values produced by the current code.  There is no danger in purging caches, but your site may appear slower for a while until the server and clients calculate new information and cache it.';
+$string['purgecachesfinished'] = 'All caches were purged.';
 $string['requestcategoryselection'] = 'Enable category selection';
 $string['restorecourse'] = 'Restore course';
 $string['restorernewroleid'] = 'Restorers\' role in courses';
index a37b84a..c71832b 100644 (file)
@@ -41,7 +41,7 @@ $string['blogaboutthis'] = 'Blog about this {$a->type}';
 $string['blogaboutthiscourse'] = 'Add an entry about this course';
 $string['blogaboutthismodule'] = 'Add an entry about this {$a}';
 $string['blogadministration'] = 'Blog administration';
-$string['blogdeleteconfirm'] = 'Delete this blog entry?';
+$string['blogdeleteconfirm'] = 'Delete the blog entry \'{$a}\'?';
 $string['blogdisable'] = 'Blogging is disabled!';
 $string['blogentries'] = 'Blog entries';
 $string['blogentriesabout'] = 'Blog entries about {$a}';
index 257bb4d..a44742e 100644 (file)
@@ -89,7 +89,7 @@ $string['editsharing'] = 'Edit sharing';
 $string['editstore'] = 'Edit store';
 $string['editstoresuccess'] = 'Succesfully edited the cache store.';
 $string['editdefinitionmappings'] = '{$a} definition store mappings';
-$string['editdefinitionsharing'] =  'Edit definition sharing for {$a}';
+$string['editdefinitionsharing'] = 'Edit definition sharing for {$a}';
 $string['ex_configcannotsave'] = 'Unable to save the cache config to file.';
 $string['ex_nodefaultlock'] = 'Unable to find a default lock instance.';
 $string['ex_unabletolock'] = 'Unable to acquire a lock for caching.';
index d35a18d..08037a1 100644 (file)
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$string['field101']='Natural and Physical Science';
-$string['field10101']='Mathematical Sciences';
-$string['field1010101']='Mathematics';
-$string['field1010103']='Statistics';
-$string['field1010199']='Mathematical Sciences (Other)';
-$string['field10103']='Physics and Astronomy';
-$string['field1010301']='Physics';
-$string['field1010303']='Astronomy';
-$string['field10105']='Chemical Sciences';
-$string['field1010501']='Organic Chemistry';
-$string['field1010503']='Inorganic Chemistry';
-$string['field1010599']='Chemical Sciences (Other)';
-$string['field10107']='Earth Sciences';
-$string['field1010701']='Atmospheric Sciences';
-$string['field1010703']='Geology';
-$string['field1010705']='Geophysics';
-$string['field1010707']='Geochemistry';
-$string['field1010709']='Soil Science';
-$string['field1010711']='Hydrology';
-$string['field1010713']='Oceanography';
-$string['field1010799']='Earth Sciences (Other)';
-$string['field10109']='Biological Sciences';
-$string['field1010901']='Biochemistry and Cell Biology';
-$string['field1010903']='Botany';
-$string['field1010905']='Ecology and Evolution';
-$string['field1010907']='Marine Science';
-$string['field1010909']='Genetics';
-$string['field1010911']='Microbiology';
-$string['field1010913']='Human Biology';
-$string['field1010915']='Zoology';
-$string['field1010999']='Biological Sciences (Other)';
-$string['field10199']='Other Natural and Physical Sciences';
-$string['field1019901']='Medical Science';
-$string['field1019903']='Forensic Science';
-$string['field1019905']='Food Science and Biotechnology';
-$string['field1019907']='Pharmacology';
-$string['field1019909']='Laboratory Technology';
-$string['field1019999']='Natural and Physical Sciences (Other)';
-$string['field102']='Information Technology';
-$string['field10201']='Computer Science';
-$string['field1020101']='Formal Language Theory';
-$string['field1020103']='Programming';
-$string['field1020105']='Computational Theory';
-$string['field1020107']='Compiler Construction';
-$string['field1020109']='Algorithms';
-$string['field1020111']='Data Structures';
-$string['field1020113']='Networks and Communications';
-$string['field1020115']='Computer Graphics';
-$string['field1020117']='Operating Systems';
-$string['field1020119']='Artificial Intelligence';
-$string['field1020199']='Computer Science (Other)';
-$string['field10203']='Information Systems';
-$string['field1020301']='Conceptual Modelling';
-$string['field1020303']='Database Management';
-$string['field1020305']='Systems Analysis and Design';
-$string['field1020307']='Decision Support Systems';
-$string['field1020399']='Information Systems (Other)';
-$string['field10299']='Other Information Technology';
-$string['field1029901']='Security Science';
-$string['field1029999']='Information Technology (Other)';
-$string['field103']='Engineering and Related Technologies';
-$string['field10301']='Manufacturing Engineering and Technology';
-$string['field1030101']='Manufacturing Engineering';
-$string['field1030103']='Printing';
-$string['field1030105']='Textile Making';
-$string['field1030107']='Garment Making';
-$string['field1030109']='Footwear Making';
-$string['field1030111']='Wood Machining and Turning';
-$string['field1030113']='Cabinet Making';
-$string['field1030115']='Furniture Upholstery and Renovation';
-$string['field1030117']='Furniture Polishing';
-$string['field1030199']='Manufacturing Engineering and Technology (Other)';
-$string['field10303']='Process and Resources Engineering';
-$string['field1030301']='Chemical Engineering';
-$string['field1030303']='Mining Engineering';
-$string['field1030305']='Materials Engineering';
-$string['field1030307']='Food Processing Technology';
-$string['field1030399']='Process and Resources Engineering (Other)';
-$string['field10305']='Automotive Engineering and Technology';
-$string['field1030501']='Automotive Engineering';
-$string['field1030503']='Vehicle Mechanics';
-$string['field1030505']='Automotive Electrics and Electronics';
-$string['field1030507']='Automotive Vehicle Refinishing';
-$string['field1030509']='Automotive Body Construction';
-$string['field1030511']='Panel Beating';
-$string['field1030513']='Upholstery and Vehicle Trimming';
-$string['field1030515']='Automotive Vehicle Operations';
-$string['field1030599']='Automotive Engineering and Technology (Other)';
-$string['field10307']='Mechanical and Industrial Engineering and Technology';
-$string['field1030701']='Mechanical Engineering';
-$string['field1030703']='Industrial Engineering';
-$string['field1030705']='Toolmaking';
-$string['field1030707']='Metal Fitting, Turning and Machining';
-$string['field1030709']='Sheetmetal Working';
-$string['field1030711']='Boilermaking and Welding';
-$string['field1030713']='Metal Casting and Patternmaking';
-$string['field1030715']='Precision Metalworking';
-$string['field1030717']='Plant and Machine Operations';
-$string['field1030799']='Mechanical and Industrial Engineering and Technology (Other)';
-$string['field10309']='Civil Engineering';
-$string['field1030901']='Construction Engineering';
-$string['field1030903']='Structural Engineering';
-$string['field1030905']='Building Services Engineering';
-$string['field1030907']='Water and Sanitary Engineering';
-$string['field1030909']='Transport Engineering';
-$string['field1030911']='Geotechnical Engineering';
-$string['field1030913']='Ocean Engineering';
-$string['field1030999']='Civil Engineering (Other)';
-$string['field10311']='Geomatic Engineering';
-$string['field1031101']='Surveying';
-$string['field1031103']='Mapping Science';
-$string['field1031199']='Geomatic Engineering (Other)';
-$string['field10313']='Electrical and Electronic Engineering and Technology';
-$string['field1031301']='Electrical Engineering';
-$string['field1031303']='Electronic Engineering';
-$string['field1031305']='Computer Engineering';
-$string['field1031307']='Communications Technologies';
-$string['field1031309']='Communications Equipment Installation and Maintenance';
-$string['field1031311']='Powerline Installation and Maintenance';
-$string['field1031313']='Electrical Fitting, Electrical Mechanics';
-$string['field1031315']='Refrigeration and Air Conditioning Mechanics';
-$string['field1031317']='Electronic Equipment Servicing';
-$string['field1031399']='Electrical and Electronic Engineering and Technology (Other)';
-$string['field10315']='Aerospace Engineering and Technology';
-$string['field1031501']='Aerospace Engineering';
-$string['field1031503']='Aircraft Maintenance Engineering';
-$string['field1031505']='Aircraft Operation';
-$string['field1031507']='Air Traffic Control';
-$string['field1031599']='Aerospace Engineering and Technology (Other)';
-$string['field10317']='Maritime Engineering and Technology';
-$string['field1031701']='Maritime Engineering';
-$string['field1031703']='Marine Construction';
-$string['field1031705']='Marine Craft Operation';
-$string['field1031799']='Maritime Engineering and Technology (Other)';
-$string['field10399']='Other Engineering and Related Technologies';
-$string['field1039901']='Environmental Engineering';
-$string['field1039903']='Biomedical Engineering';
-$string['field1039905']='Fire Technology';
-$string['field1039907']='Rail Operations';
-$string['field1039909']='Cleaning';
-$string['field1039999']='Engineering and Related Technologies (Other)';
-$string['field104']='Architecture and Building';
-$string['field10401']='Architecture and Urban Environment';
-$string['field1040101']='Architecture';
-$string['field1040103']='Urban Design and Regional Planning';
-$string['field1040105']='Landscape Architecture';
-$string['field1040107']='Interior and Environmental Design';
-$string['field1040199']='Architecture and Urban Environment (Other)';
-$string['field10403']='Building';
-$string['field1040301']='Building Science and Technology';
-$string['field1040303']='Building Construction Management';
-$string['field1040305']='Building Surveying';
-$string['field1040307']='Building Construction Economics';
-$string['field1040309']='Bricklaying and Stonemasonry';
-$string['field1040311']='Carpentry and Joinery';
-$string['field1040313']='Ceiling, Wall and Floor Fixing';
-$string['field1040315']='Roof Fixing';
-$string['field1040317']='Plastering';
-$string['field1040319']='Furnishing Installation';
-$string['field1040321']='Floor Coverings';
-$string['field1040323']='Glazing';
-$string['field1040325']='Painting, Decorating and Sign Writing';
-$string['field1040327']='Plumbing';
-$string['field1040329']='Scaffolding and Rigging';
-$string['field1040399']='Building (Other)';
-$string['field105']='Agriculture, Environmental and Related Studies';
-$string['field10501']='Agriculture';
-$string['field1050101']='Agricultural Science';
-$string['field1050103']='Wool Science';
-$string['field1050105']='Animal Husbandry';
-$string['field1050199']='Agriculture (Other)';
-$string['field10503']='Horticulture and Viticulture';
-$string['field1050301']='Horticulture';
-$string['field1050303']='Viticulture';
-$string['field10505']='Forestry Studies';
-$string['field1050501']='Forestry Studies';
-$string['field10507']='Fisheries Studies';
-$string['field1050701']='Aquaculture';
-$string['field1050799']='Fisheries Studies (Other)';
-$string['field10509']='Environmental Studies';
-$string['field1050901']='Land, Parks and Wildlife Management';
-$string['field1050999']='Environmental Studies (Other)';
-$string['field10599']='Other Agriculture, Environmental and Related Studies';
-$string['field1059901']='Pest and Weed Control';
-$string['field1059999']='Agriculture, Environmental and Related Studies (Other)';
-$string['field106']='Health';
-$string['field10601']='Medical Studies';
-$string['field1060101']='General Medicine';
-$string['field1060103']='Surgery';
-$string['field1060105']='Psychiatry';
-$string['field1060107']='Obstetrics and Gynaecology';
-$string['field1060109']='Paediatrics';
-$string['field1060111']='Anaesthesiology';
-$string['field1060113']='Pathology';
-$string['field1060115']='Radiology';
-$string['field1060117']='Internal Medicine';
-$string['field1060119']='General Practice';
-$string['field1060199']='Medical Studies (Other)';
-$string['field10603']='Nursing';
-$string['field1060301']='General Nursing';
-$string['field1060303']='Midwifery';
-$string['field1060305']='Mental Health Nursing';
-$string['field1060307']='Community Nursing';
-$string['field1060309']='Critical Care Nursing';
-$string['field1060311']='Aged Care Nursing';
-$string['field1060313']='Palliative Care Nursing';
-$string['field1060315']='Mothercraft Nursing and Family and Child Health Nursing';
-$string['field1060399']='Nursing (Other)';
-$string['field10605']='Pharmacy';
-$string['field1060501']='Pharmacy';
-$string['field10607']='Dental Studies';
-$string['field1060701']='Dentistry';
-$string['field1060703']='Dental Assisting';
-$string['field1060705']='Dental Technology';
-$string['field1060799']='Dental Studies (Other)';
-$string['field10609']='Optical Science';
-$string['field1060901']='Optometry';
-$string['field1060903']='Optical Technology';
-$string['field1060999']='Optical Science (Other)';
-$string['field10611']='Veterinary Studies';
-$string['field1061101']='Veterinary Science';
-$string['field1061103']='Veterinary Assisting';
-$string['field1061199']='Veterinary Studies (Other)';
-$string['field10613']='Public Health';
-$string['field1061301']='Occupational Health and Safety';
-$string['field1061303']='Environmental Health';
-$string['field1061305']='Indigenous Health';
-$string['field1061307']='Health Promotion';
-$string['field1061309']='Community Health';
-$string['field1061311']='Epidemiology';
-$string['field1061399']='Public Health (Other)';
-$string['field10615']='Radiography';
-$string['field1061501']='Radiography';
-$string['field10617']='Rehabilitation Therapies';
-$string['field1061701']='Physiotherapy';
-$string['field1061703']='Occupational Therapy';
-$string['field1061705']='Chiropractic and Osteopathy';
-$string['field1061707']='Speech Pathology';
-$string['field1061709']='Audiology';
-$string['field1061711']='Massage Therapy';
-$string['field1061713']='Podiatry';
-$string['field1061799']='Rehabilitation Therapies (Other)';
-$string['field10619']='Complementary Therapies';
-$string['field1061901']='Naturopathy';
-$string['field1061903']='Acupuncture';
-$string['field1061905']='Traditional Chinese Medicine';
-$string['field1061999']='Complementary Therapies (Other)';
-$string['field10699']='Other Health';
-$string['field1069901']='Nutrition and Dietetics';
-$string['field1069903']='Human Movement';
-$string['field1069905']='Paramedical Studies';
-$string['field1069907']='First Aid';
-$string['field1069999']='Health (Other)';
-$string['field107']='Education';
-$string['field10701']='Teacher Education';
-$string['field1070101']='Teacher Education: Early Childhood';
-$string['field1070103']='Teacher Education: Primary';
-$string['field1070105']='Teacher Education: Secondary';
-$string['field1070107']='Teacher-Librarianship';
-$string['field1070109']='Teacher Education: Vocational Education and Training';
-$string['field1070111']='Teacher Education: Higher Education';
-$string['field1070113']='Teacher Education: Special Education';
-$string['field1070115']='English As A Second Language Teaching';
-$string['field1070117']='Nursing Education Teacher Training';
-$string['field1070199']='Teacher Education (Other)';
-$string['field10703']='Curriculum and Education Studies';
-$string['field1070301']='Curriculum Studies';
-$string['field1070303']='Education Studies';
-$string['field10799']='Other Education';
-$string['field1079999']='Education (Other)';
-$string['field108']='Management and Commerce';
-$string['field10801']='Accounting';
-$string['field1080101']='Accounting';
-$string['field10803']='Business and Management';
-$string['field1080301']='Business Management';
-$string['field1080303']='Human Resource Management';
-$string['field1080305']='Personal Management Training';
-$string['field1080307']='Organisation Management';
-$string['field1080309']='Industrial Relations';
-$string['field1080311']='International Business';
-$string['field1080313']='Public and Health Care Administration';
-$string['field1080315']='Project Management';
-$string['field1080317']='Quality Management';
-$string['field1080319']='Hospitality Management';
-$string['field1080321']='Farm Management and Agribusiness';
-$string['field1080323']='Tourism Management';
-$string['field1080399']='Business and Management (Other)';
-$string['field10805']='Sales and Marketing';
-$string['field1080501']='Sales';
-$string['field1080503']='Real Estate';
-$string['field1080505']='Marketing';
-$string['field1080507']='Advertising';
-$string['field1080509']='Public Relations';
-$string['field1080599']='Sales and Marketing (Other)';
-$string['field10807']='Tourism';
-$string['field1080701']='Tourism';
-$string['field10809']='Office Studies';
-$string['field1080901']='Secretarial and Clerical Studies';
-$string['field1080903']='Keyboard Skills';
-$string['field1080905']='Practical Computing Skills';
-$string['field1080999']='Office Studies (Other)';
-$string['field10811']='Banking, Finance and Related Fields';
-$string['field1081101']='Banking and Finance';
-$string['field1081103']='Insurance and Actuarial Studies';
-$string['field1081105']='Investment and Securities';
-$string['field1081199']='Banking, Finance and Related Fields (Other)';
-$string['field10899']='Other Management and Commerce';
-$string['field1089901']='Purchasing, Warehousing and Distribution';
-$string['field1089903']='Valuation';
-$string['field1089999']='Management and Commerce (Other)';
-$string['field109']='Society and Culture';
-$string['field10901']='Political Science and Policy Studies';
-$string['field1090101']='Political Science';
-$string['field1090103']='Policy Studies';
-$string['field10903']='Studies In Human Society';
-$string['field1090301']='Sociology';
-$string['field1090303']='Anthropology';
-$string['field1090305']='History';
-$string['field1090307']='Archaeology';
-$string['field1090309']='Human Geography';
-$string['field1090311']='Indigenous Studies';
-$string['field1090313']='Gender Specific Studies';
-$string['field1090399']='Studies In Human Society (Other)';
-$string['field10905']='Human Welfare Studies and Services';
-$string['field1090501']='Social Work';
-$string['field1090503']='Children\'S Services';
-$string['field1090505']='Youth Work';
-$string['field1090507']='Care For The Aged';
-$string['field1090509']='Care For The Disabled';
-$string['field1090511']='Residential Client Care';
-$string['field1090513']='Counselling';
-$string['field1090515']='Welfare Studies';
-$string['field1090599']='Human Welfare Studies and Services (Other)';
-$string['field10907']='Behavioural Science';
-$string['field1090701']='Psychology';
-$string['field1090799']='Behavioural Science (Other)';
-$string['field10909']='Law';
-$string['field1090901']='Business and Commercial Law';
-$string['field1090903']='Constitutional Law';
-$string['field1090905']='Criminal Law';
-$string['field1090907']='Family Law';
-$string['field1090909']='International Law';
-$string['field1090911']='Taxation Law';
-$string['field1090913']='Legal Practice';
-$string['field1090999']='Law (Other)';
-$string['field10911']='Justice and Law Enforcement';
-$string['field1091101']='Justice Administration';
-$string['field1091103']='Legal Studies';
-$string['field1091105']='Police Studies';
-$string['field1091199']='Justice and Law Enforcement (Other)';
-$string['field10913']='Librarianship, Information Management and Curatorial Studies';
-$string['field1091301']='Librarianship and Information Management';
-$string['field1091303']='Curatorial Studies';
-$string['field10915']='Language and Literature';
-$string['field1091501']='English Language';
-$string['field1091503']='Northern European Languages';
-$string['field1091505']='Southern European Languages';
-$string['field1091507']='Eastern European Languages';
-$string['field1091509']='Southwest Asian and North African Languages';
-$string['field1091511']='Southern Asian Languages';
-$string['field1091513']='Southeast Asian Languages';
-$string['field1091515']='Eastern Asian Languages';
-$string['field1091517']='Australian Indigenous Languages';
-$string['field1091519']='Translating and Interpreting';
-$string['field1091521']='Linguistics';
-$string['field1091523']='Literature';
-$string['field1091599']='Language and Literature (Other)';
-$string['field10917']='Philosophy and Religious Studies';
-$string['field1091701']='Philosophy';
-$string['field1091703']='Religious Studies';
-$string['field10919']='Economics and Econometrics';
-$string['field1091901']='Economics';
-$string['field1091903']='Econometrics';
-$string['field10921']='Sport and Recreation';
-$string['field1092101']='Sport and Recreation Activities';
-$string['field1092103']='Sports Coaching, Officiating and Instruction';
-$string['field1092199']='Sport and Recreation (Other)';
-$string['field10999']='Other Society and Culture';
-$string['field1099901']='Family and Consumer Studies';
-$string['field1099903']='Criminology';
-$string['field1099905']='Security Services';
-$string['field1099999']='Society and Culture (Other)';
-$string['field110']='Creative Arts';
-$string['field11001']='Performing Arts';
-$string['field1100101']='Music';
-$string['field1100103']='Drama and Theatre Studies';
-$string['field1100105']='Dance';
-$string['field1100199']='Performing Arts (Other)';
-$string['field11003']='Visual Arts and Crafts';
-$string['field1100301']='Fine Arts';
-$string['field1100303']='Photography';
-$string['field1100305']='Crafts';
-$string['field1100307']='Jewellery Making';
-$string['field1100309']='Floristry';
-$string['field1100399']='Visual Arts and Crafts (Other)';
-$string['field11005']='Graphic and Design Studies';
-$string['field1100501']='Graphic Arts and Design Studies';
-$string['field1100503']='Textile Design';
-$string['field1100505']='Fashion Design';
-$string['field1100599']='Graphic and Design Studies (Other)';
-$string['field11007']='Communication and Media Studies';
-$string['field1100701']='Audio Visual Studies';
-$string['field1100703']='Journalism';
-$string['field1100705']='Written Communication';
-$string['field1100707']='Verbal Communication';
-$string['field1100799']='Communication and Media Studies (Other)';
-$string['field11099']='Other Creative Arts';
-$string['field1109999']='Creative Arts (Other)';
-$string['field111']='Food, Hospitality and Personal Services';
-$string['field11101']='Food and Hospitality';
-$string['field1110101']='Hospitality';
-$string['field1110103']='Food and Beverage Service';
-$string['field1110105']='Butchery';
-$string['field1110107']='Baking and Pastrymaking';
-$string['field1110109']='Cookery';
-$string['field1110111']='Food Hygiene';
-$string['field1110199']='Food and Hospitality (Other)';
-$string['field11103']='Personal Services';
-$string['field1110301']='Beauty Therapy';
-$string['field1110303']='Hairdressing';
-$string['field1110399']='Personal Services (Other)';
-$string['field112']='Mixed Field Programmes';
-$string['field11201']='General Education Programmes';
-$string['field1120101']='General Primary and Secondary Education Programmes';
-$string['field1120103']='Literacy and Numeracy Programmes';
-$string['field1120105']='Learning Skills Programmes';
-$string['field1120199']='General Education Programmes (Other)';
-$string['field11203']='Social Skills Programmes';
-$string['field1120301']='Social and Interpersonal Skills Programmes';
-$string['field1120303']='Survival Skills Programmes';
-$string['field1120305']='Parental Education Programmes';
-$string['field1120399']='Social Skills Programmes (Other)';
-$string['field11205']='Employment Skills Programmes';
-$string['field1120501']='Career Development Programmes';
-$string['field1120503']='Job Search Skills Programmes';
-$string['field1120505']='Work Practices Programmes';
-$string['field1120599']='Employment Skills Programmes (Other)';
-$string['field11299']='Other Mixed Field Programmes';
-$string['field1129999']='Mixed Field Programmes (Other)';
+$string['field101'] = 'Natural and Physical Science';
+$string['field10101'] = 'Mathematical Sciences';
+$string['field1010101'] = 'Mathematics';
+$string['field1010103'] = 'Statistics';
+$string['field1010199'] = 'Mathematical Sciences (Other)';
+$string['field10103'] = 'Physics and Astronomy';
+$string['field1010301'] = 'Physics';
+$string['field1010303'] = 'Astronomy';
+$string['field10105'] = 'Chemical Sciences';
+$string['field1010501'] = 'Organic Chemistry';
+$string['field1010503'] = 'Inorganic Chemistry';
+$string['field1010599'] = 'Chemical Sciences (Other)';
+$string['field10107'] = 'Earth Sciences';
+$string['field1010701'] = 'Atmospheric Sciences';
+$string['field1010703'] = 'Geology';
+$string['field1010705'] = 'Geophysics';
+$string['field1010707'] = 'Geochemistry';
+$string['field1010709'] = 'Soil Science';
+$string['field1010711'] = 'Hydrology';
+$string['field1010713'] = 'Oceanography';
+$string['field1010799'] = 'Earth Sciences (Other)';
+$string['field10109'] = 'Biological Sciences';
+$string['field1010901'] = 'Biochemistry and Cell Biology';
+$string['field1010903'] = 'Botany';
+$string['field1010905'] = 'Ecology and Evolution';
+$string['field1010907'] = 'Marine Science';
+$string['field1010909'] = 'Genetics';
+$string['field1010911'] = 'Microbiology';
+$string['field1010913'] = 'Human Biology';
+$string['field1010915'] = 'Zoology';
+$string['field1010999'] = 'Biological Sciences (Other)';
+$string['field10199'] = 'Other Natural and Physical Sciences';
+$string['field1019901'] = 'Medical Science';
+$string['field1019903'] = 'Forensic Science';
+$string['field1019905'] = 'Food Science and Biotechnology';
+$string['field1019907'] = 'Pharmacology';
+$string['field1019909'] = 'Laboratory Technology';
+$string['field1019999'] = 'Natural and Physical Sciences (Other)';
+$string['field102'] = 'Information Technology';
+$string['field10201'] = 'Computer Science';
+$string['field1020101'] = 'Formal Language Theory';
+$string['field1020103'] = 'Programming';
+$string['field1020105'] = 'Computational Theory';
+$string['field1020107'] = 'Compiler Construction';
+$string['field1020109'] = 'Algorithms';
+$string['field1020111'] = 'Data Structures';
+$string['field1020113'] = 'Networks and Communications';
+$string['field1020115'] = 'Computer Graphics';
+$string['field1020117'] = 'Operating Systems';
+$string['field1020119'] = 'Artificial Intelligence';
+$string['field1020199'] = 'Computer Science (Other)';
+$string['field10203'] = 'Information Systems';
+$string['field1020301'] = 'Conceptual Modelling';
+$string['field1020303'] = 'Database Management';
+$string['field1020305'] = 'Systems Analysis and Design';
+$string['field1020307'] = 'Decision Support Systems';
+$string['field1020399'] = 'Information Systems (Other)';
+$string['field10299'] = 'Other Information Technology';
+$string['field1029901'] = 'Security Science';
+$string['field1029999'] = 'Information Technology (Other)';
+$string['field103'] = 'Engineering and Related Technologies';
+$string['field10301'] = 'Manufacturing Engineering and Technology';
+$string['field1030101'] = 'Manufacturing Engineering';
+$string['field1030103'] = 'Printing';
+$string['field1030105'] = 'Textile Making';
+$string['field1030107'] = 'Garment Making';
+$string['field1030109'] = 'Footwear Making';
+$string['field1030111'] = 'Wood Machining and Turning';
+$string['field1030113'] = 'Cabinet Making';
+$string['field1030115'] = 'Furniture Upholstery and Renovation';
+$string['field1030117'] = 'Furniture Polishing';
+$string['field1030199'] = 'Manufacturing Engineering and Technology (Other)';
+$string['field10303'] = 'Process and Resources Engineering';
+$string['field1030301'] = 'Chemical Engineering';
+$string['field1030303'] = 'Mining Engineering';
+$string['field1030305'] = 'Materials Engineering';
+$string['field1030307'] = 'Food Processing Technology';
+$string['field1030399'] = 'Process and Resources Engineering (Other)';
+$string['field10305'] = 'Automotive Engineering and Technology';
+$string['field1030501'] = 'Automotive Engineering';
+$string['field1030503'] = 'Vehicle Mechanics';
+$string['field1030505'] = 'Automotive Electrics and Electronics';
+$string['field1030507'] = 'Automotive Vehicle Refinishing';
+$string['field1030509'] = 'Automotive Body Construction';
+$string['field1030511'] = 'Panel Beating';
+$string['field1030513'] = 'Upholstery and Vehicle Trimming';
+$string['field1030515'] = 'Automotive Vehicle Operations';
+$string['field1030599'] = 'Automotive Engineering and Technology (Other)';
+$string['field10307'] = 'Mechanical and Industrial Engineering and Technology';
+$string['field1030701'] = 'Mechanical Engineering';
+$string['field1030703'] = 'Industrial Engineering';
+$string['field1030705'] = 'Toolmaking';
+$string['field1030707'] = 'Metal Fitting, Turning and Machining';
+$string['field1030709'] = 'Sheetmetal Working';
+$string['field1030711'] = 'Boilermaking and Welding';
+$string['field1030713'] = 'Metal Casting and Patternmaking';
+$string['field1030715'] = 'Precision Metalworking';
+$string['field1030717'] = 'Plant and Machine Operations';
+$string['field1030799'] = 'Mechanical and Industrial Engineering and Technology (Other)';
+$string['field10309'] = 'Civil Engineering';
+$string['field1030901'] = 'Construction Engineering';
+$string['field1030903'] = 'Structural Engineering';
+$string['field1030905'] = 'Building Services Engineering';
+$string['field1030907'] = 'Water and Sanitary Engineering';
+$string['field1030909'] = 'Transport Engineering';
+$string['field1030911'] = 'Geotechnical Engineering';
+$string['field1030913'] = 'Ocean Engineering';
+$string['field1030999'] = 'Civil Engineering (Other)';
+$string['field10311'] = 'Geomatic Engineering';
+$string['field1031101'] = 'Surveying';
+$string['field1031103'] = 'Mapping Science';
+$string['field1031199'] = 'Geomatic Engineering (Other)';
+$string['field10313'] = 'Electrical and Electronic Engineering and Technology';
+$string['field1031301'] = 'Electrical Engineering';
+$string['field1031303'] = 'Electronic Engineering';
+$string['field1031305'] = 'Computer Engineering';
+$string['field1031307'] = 'Communications Technologies';
+$string['field1031309'] = 'Communications Equipment Installation and Maintenance';
+$string['field1031311'] = 'Powerline Installation and Maintenance';
+$string['field1031313'] = 'Electrical Fitting, Electrical Mechanics';
+$string['field1031315'] = 'Refrigeration and Air Conditioning Mechanics';
+$string['field1031317'] = 'Electronic Equipment Servicing';
+$string['field1031399'] = 'Electrical and Electronic Engineering and Technology (Other)';
+$string['field10315'] = 'Aerospace Engineering and Technology';
+$string['field1031501'] = 'Aerospace Engineering';
+$string['field1031503'] = 'Aircraft Maintenance Engineering';
+$string['field1031505'] = 'Aircraft Operation';
+$string['field1031507'] = 'Air Traffic Control';
+$string['field1031599'] = 'Aerospace Engineering and Technology (Other)';
+$string['field10317'] = 'Maritime Engineering and Technology';
+$string['field1031701'] = 'Maritime Engineering';
+$string['field1031703'] = 'Marine Construction';
+$string['field1031705'] = 'Marine Craft Operation';
+$string['field1031799'] = 'Maritime Engineering and Technology (Other)';
+$string['field10399'] = 'Other Engineering and Related Technologies';
+$string['field1039901'] = 'Environmental Engineering';
+$string['field1039903'] = 'Biomedical Engineering';
+$string['field1039905'] = 'Fire Technology';
+$string['field1039907'] = 'Rail Operations';
+$string['field1039909'] = 'Cleaning';
+$string['field1039999'] = 'Engineering and Related Technologies (Other)';
+$string['field104'] = 'Architecture and Building';
+$string['field10401'] = 'Architecture and Urban Environment';
+$string['field1040101'] = 'Architecture';
+$string['field1040103'] = 'Urban Design and Regional Planning';
+$string['field1040105'] = 'Landscape Architecture';
+$string['field1040107'] = 'Interior and Environmental Design';
+$string['field1040199'] = 'Architecture and Urban Environment (Other)';
+$string['field10403'] = 'Building';
+$string['field1040301'] = 'Building Science and Technology';
+$string['field1040303'] = 'Building Construction Management';
+$string['field1040305'] = 'Building Surveying';
+$string['field1040307'] = 'Building Construction Economics';
+$string['field1040309'] = 'Bricklaying and Stonemasonry';
+$string['field1040311'] = 'Carpentry and Joinery';
+$string['field1040313'] = 'Ceiling, Wall and Floor Fixing';
+$string['field1040315'] = 'Roof Fixing';
+$string['field1040317'] = 'Plastering';
+$string['field1040319'] = 'Furnishing Installation';
+$string['field1040321'] = 'Floor Coverings';
+$string['field1040323'] = 'Glazing';
+$string['field1040325'] = 'Painting, Decorating and Sign Writing';
+$string['field1040327'] = 'Plumbing';
+$string['field1040329'] = 'Scaffolding and Rigging';
+$string['field1040399'] = 'Building (Other)';
+$string['field105'] = 'Agriculture, Environmental and Related Studies';
+$string['field10501'] = 'Agriculture';
+$string['field1050101'] = 'Agricultural Science';
+$string['field1050103'] = 'Wool Science';
+$string['field1050105'] = 'Animal Husbandry';
+$string['field1050199'] = 'Agriculture (Other)';
+$string['field10503'] = 'Horticulture and Viticulture';
+$string['field1050301'] = 'Horticulture';
+$string['field1050303'] = 'Viticulture';
+$string['field10505'] = 'Forestry Studies';
+$string['field1050501'] = 'Forestry Studies';
+$string['field10507'] = 'Fisheries Studies';
+$string['field1050701'] = 'Aquaculture';
+$string['field1050799'] = 'Fisheries Studies (Other)';
+$string['field10509'] = 'Environmental Studies';
+$string['field1050901'] = 'Land, Parks and Wildlife Management';
+$string['field1050999'] = 'Environmental Studies (Other)';
+$string['field10599'] = 'Other Agriculture, Environmental and Related Studies';
+$string['field1059901'] = 'Pest and Weed Control';
+$string['field1059999'] = 'Agriculture, Environmental and Related Studies (Other)';
+$string['field106'] = 'Health';
+$string['field10601'] = 'Medical Studies';
+$string['field1060101'] = 'General Medicine';
+$string['field1060103'] = 'Surgery';
+$string['field1060105'] = 'Psychiatry';
+$string['field1060107'] = 'Obstetrics and Gynaecology';
+$string['field1060109'] = 'Paediatrics';
+$string['field1060111'] = 'Anaesthesiology';
+$string['field1060113'] = 'Pathology';
+$string['field1060115'] = 'Radiology';
+$string['field1060117'] = 'Internal Medicine';
+$string['field1060119'] = 'General Practice';
+$string['field1060199'] = 'Medical Studies (Other)';
+$string['field10603'] = 'Nursing';
+$string['field1060301'] = 'General Nursing';
+$string['field1060303'] = 'Midwifery';
+$string['field1060305'] = 'Mental Health Nursing';
+$string['field1060307'] = 'Community Nursing';
+$string['field1060309'] = 'Critical Care Nursing';
+$string['field1060311'] = 'Aged Care Nursing';
+$string['field1060313'] = 'Palliative Care Nursing';
+$string['field1060315'] = 'Mothercraft Nursing and Family and Child Health Nursing';
+$string['field1060399'] = 'Nursing (Other)';
+$string['field10605'] = 'Pharmacy';
+$string['field1060501'] = 'Pharmacy';
+$string['field10607'] = 'Dental Studies';
+$string['field1060701'] = 'Dentistry';
+$string['field1060703'] = 'Dental Assisting';
+$string['field1060705'] = 'Dental Technology';
+$string['field1060799'] = 'Dental Studies (Other)';
+$string['field10609'] = 'Optical Science';
+$string['field1060901'] = 'Optometry';
+$string['field1060903'] = 'Optical Technology';
+$string['field1060999'] = 'Optical Science (Other)';
+$string['field10611'] = 'Veterinary Studies';
+$string['field1061101'] = 'Veterinary Science';
+$string['field1061103'] = 'Veterinary Assisting';
+$string['field1061199'] = 'Veterinary Studies (Other)';
+$string['field10613'] = 'Public Health';
+$string['field1061301'] = 'Occupational Health and Safety';
+$string['field1061303'] = 'Environmental Health';
+$string['field1061305'] = 'Indigenous Health';
+$string['field1061307'] = 'Health Promotion';
+$string['field1061309'] = 'Community Health';
+$string['field1061311'] = 'Epidemiology';
+$string['field1061399'] = 'Public Health (Other)';
+$string['field10615'] = 'Radiography';
+$string['field1061501'] = 'Radiography';
+$string['field10617'] = 'Rehabilitation Therapies';
+$string['field1061701'] = 'Physiotherapy';
+$string['field1061703'] = 'Occupational Therapy';
+$string['field1061705'] = 'Chiropractic and Osteopathy';
+$string['field1061707'] = 'Speech Pathology';
+$string['field1061709'] = 'Audiology';
+$string['field1061711'] = 'Massage Therapy';
+$string['field1061713'] = 'Podiatry';
+$string['field1061799'] = 'Rehabilitation Therapies (Other)';
+$string['field10619'] = 'Complementary Therapies';
+$string['field1061901'] = 'Naturopathy';
+$string['field1061903'] = 'Acupuncture';
+$string['field1061905'] = 'Traditional Chinese Medicine';
+$string['field1061999'] = 'Complementary Therapies (Other)';
+$string['field10699'] = 'Other Health';
+$string['field1069901'] = 'Nutrition and Dietetics';
+$string['field1069903'] = 'Human Movement';
+$string['field1069905'] = 'Paramedical Studies';
+$string['field1069907'] = 'First Aid';
+$string['field1069999'] = 'Health (Other)';
+$string['field107'] = 'Education';
+$string['field10701'] = 'Teacher Education';
+$string['field1070101'] = 'Teacher Education: Early Childhood';
+$string['field1070103'] = 'Teacher Education: Primary';
+$string['field1070105'] = 'Teacher Education: Secondary';
+$string['field1070107'] = 'Teacher-Librarianship';
+$string['field1070109'] = 'Teacher Education: Vocational Education and Training';
+$string['field1070111'] = 'Teacher Education: Higher Education';
+$string['field1070113'] = 'Teacher Education: Special Education';
+$string['field1070115'] = 'English As A Second Language Teaching';
+$string['field1070117'] = 'Nursing Education Teacher Training';
+$string['field1070199'] = 'Teacher Education (Other)';
+$string['field10703'] = 'Curriculum and Education Studies';
+$string['field1070301'] = 'Curriculum Studies';
+$string['field1070303'] = 'Education Studies';
+$string['field10799'] = 'Other Education';
+$string['field1079999'] = 'Education (Other)';
+$string['field108'] = 'Management and Commerce';
+$string['field10801'] = 'Accounting';
+$string['field1080101'] = 'Accounting';
+$string['field10803'] = 'Business and Management';
+$string['field1080301'] = 'Business Management';
+$string['field1080303'] = 'Human Resource Management';
+$string['field1080305'] = 'Personal Management Training';
+$string['field1080307'] = 'Organisation Management';
+$string['field1080309'] = 'Industrial Relations';
+$string['field1080311'] = 'International Business';
+$string['field1080313'] = 'Public and Health Care Administration';
+$string['field1080315'] = 'Project Management';
+$string['field1080317'] = 'Quality Management';
+$string['field1080319'] = 'Hospitality Management';
+$string['field1080321'] = 'Farm Management and Agribusiness';
+$string['field1080323'] = 'Tourism Management';
+$string['field1080399'] = 'Business and Management (Other)';
+$string['field10805'] = 'Sales and Marketing';
+$string['field1080501'] = 'Sales';
+$string['field1080503'] = 'Real Estate';
+$string['field1080505'] = 'Marketing';
+$string['field1080507'] = 'Advertising';
+$string['field1080509'] = 'Public Relations';
+$string['field1080599'] = 'Sales and Marketing (Other)';
+$string['field10807'] = 'Tourism';
+$string['field1080701'] = 'Tourism';
+$string['field10809'] = 'Office Studies';
+$string['field1080901'] = 'Secretarial and Clerical Studies';
+$string['field1080903'] = 'Keyboard Skills';
+$string['field1080905'] = 'Practical Computing Skills';
+$string['field1080999'] = 'Office Studies (Other)';
+$string['field10811'] = 'Banking, Finance and Related Fields';
+$string['field1081101'] = 'Banking and Finance';
+$string['field1081103'] = 'Insurance and Actuarial Studies';
+$string['field1081105'] = 'Investment and Securities';
+$string['field1081199'] = 'Banking, Finance and Related Fields (Other)';
+$string['field10899'] = 'Other Management and Commerce';
+$string['field1089901'] = 'Purchasing, Warehousing and Distribution';
+$string['field1089903'] = 'Valuation';
+$string['field1089999'] = 'Management and Commerce (Other)';
+$string['field109'] = 'Society and Culture';
+$string['field10901'] = 'Political Science and Policy Studies';
+$string['field1090101'] = 'Political Science';
+$string['field1090103'] = 'Policy Studies';
+$string['field10903'] = 'Studies In Human Society';
+$string['field1090301'] = 'Sociology';
+$string['field1090303'] = 'Anthropology';
+$string['field1090305'] = 'History';
+$string['field1090307'] = 'Archaeology';
+$string['field1090309'] = 'Human Geography';
+$string['field1090311'] = 'Indigenous Studies';
+$string['field1090313'] = 'Gender Specific Studies';
+$string['field1090399'] = 'Studies In Human Society (Other)';
+$string['field10905'] = 'Human Welfare Studies and Services';
+$string['field1090501'] = 'Social Work';
+$string['field1090503'] = 'Children\'S Services';
+$string['field1090505'] = 'Youth Work';
+$string['field1090507'] = 'Care For The Aged';
+$string['field1090509'] = 'Care For The Disabled';
+$string['field1090511'] = 'Residential Client Care';
+$string['field1090513'] = 'Counselling';
+$string['field1090515'] = 'Welfare Studies';
+$string['field1090599'] = 'Human Welfare Studies and Services (Other)';
+$string['field10907'] = 'Behavioural Science';
+$string['field1090701'] = 'Psychology';
+$string['field1090799'] = 'Behavioural Science (Other)';
+$string['field10909'] = 'Law';
+$string['field1090901'] = 'Business and Commercial Law';
+$string['field1090903'] = 'Constitutional Law';
+$string['field1090905'] = 'Criminal Law';
+$string['field1090907'] = 'Family Law';
+$string['field1090909'] = 'International Law';
+$string['field1090911'] = 'Taxation Law';
+$string['field1090913'] = 'Legal Practice';
+$string['field1090999'] = 'Law (Other)';
+$string['field10911'] = 'Justice and Law Enforcement';
+$string['field1091101'] = 'Justice Administration';
+$string['field1091103'] = 'Legal Studies';
+$string['field1091105'] = 'Police Studies';
+$string['field1091199'] = 'Justice and Law Enforcement (Other)';
+$string['field10913'] = 'Librarianship, Information Management and Curatorial Studies';
+$string['field1091301'] = 'Librarianship and Information Management';
+$string['field1091303'] = 'Curatorial Studies';
+$string['field10915'] = 'Language and Literature';
+$string['field1091501'] = 'English Language';
+$string['field1091503'] = 'Northern European Languages';
+$string['field1091505'] = 'Southern European Languages';
+$string['field1091507'] = 'Eastern European Languages';
+$string['field1091509'] = 'Southwest Asian and North African Languages';
+$string['field1091511'] = 'Southern Asian Languages';
+$string['field1091513'] = 'Southeast Asian Languages';
+$string['field1091515'] = 'Eastern Asian Languages';
+$string['field1091517'] = 'Australian Indigenous Languages';
+$string['field1091519'] = 'Translating and Interpreting';
+$string['field1091521'] = 'Linguistics';
+$string['field1091523'] = 'Literature';
+$string['field1091599'] = 'Language and Literature (Other)';
+$string['field10917'] = 'Philosophy and Religious Studies';
+$string['field1091701'] = 'Philosophy';
+$string['field1091703'] = 'Religious Studies';
+$string['field10919'] = 'Economics and Econometrics';
+$string['field1091901'] = 'Economics';
+$string['field1091903'] = 'Econometrics';
+$string['field10921'] = 'Sport and Recreation';
+$string['field1092101'] = 'Sport and Recreation Activities';
+$string['field1092103'] = 'Sports Coaching, Officiating and Instruction';
+$string['field1092199'] = 'Sport and Recreation (Other)';
+$string['field10999'] = 'Other Society and Culture';
+$string['field1099901'] = 'Family and Consumer Studies';
+$string['field1099903'] = 'Criminology';
+$string['field1099905'] = 'Security Services';
+$string['field1099999'] = 'Society and Culture (Other)';
+$string['field110'] = 'Creative Arts';
+$string['field11001'] = 'Performing Arts';
+$string['field1100101'] = 'Music';
+$string['field1100103'] = 'Drama and Theatre Studies';
+$string['field1100105'] = 'Dance';
+$string['field1100199'] = 'Performing Arts (Other)';
+$string['field11003'] = 'Visual Arts and Crafts';
+$string['field1100301'] = 'Fine Arts';
+$string['field1100303'] = 'Photography';
+$string['field1100305'] = 'Crafts';
+$string['field1100307'] = 'Jewellery Making';
+$string['field1100309'] = 'Floristry';
+$string['field1100399'] = 'Visual Arts and Crafts (Other)';
+$string['field11005'] = 'Graphic and Design Studies';
+$string['field1100501'] = 'Graphic Arts and Design Studies';
+$string['field1100503'] = 'Textile Design';
+$string['field1100505'] = 'Fashion Design';
+$string['field1100599'] = 'Graphic and Design Studies (Other)';
+$string['field11007'] = 'Communication and Media Studies';
+$string['field1100701'] = 'Audio Visual Studies';
+$string['field1100703'] = 'Journalism';
+$string['field1100705'] = 'Written Communication';
+$string['field1100707'] = 'Verbal Communication';
+$string['field1100799'] = 'Communication and Media Studies (Other)';
+$string['field11099'] = 'Other Creative Arts';
+$string['field1109999'] = 'Creative Arts (Other)';
+$string['field111'] = 'Food, Hospitality and Personal Services';
+$string['field11101'] = 'Food and Hospitality';
+$string['field1110101'] = 'Hospitality';
+$string['field1110103'] = 'Food and Beverage Service';
+$string['field1110105'] = 'Butchery';
+$string['field1110107'] = 'Baking and Pastrymaking';
+$string['field1110109'] = 'Cookery';
+$string['field1110111'] = 'Food Hygiene';
+$string['field1110199'] = 'Food and Hospitality (Other)';
+$string['field11103'] = 'Personal Services';
+$string['field1110301'] = 'Beauty Therapy';
+$string['field1110303'] = 'Hairdressing';
+$string['field1110399'] = 'Personal Services (Other)';
+$string['field112'] = 'Mixed Field Programmes';
+$string['field11201'] = 'General Education Programmes';
+$string['field1120101'] = 'General Primary and Secondary Education Programmes';
+$string['field1120103'] = 'Literacy and Numeracy Programmes';
+$string['field1120105'] = 'Learning Skills Programmes';
+$string['field1120199'] = 'General Education Programmes (Other)';
+$string['field11203'] = 'Social Skills Programmes';
+$string['field1120301'] = 'Social and Interpersonal Skills Programmes';
+$string['field1120303'] = 'Survival Skills Programmes';
+$string['field1120305'] = 'Parental Education Programmes';
+$string['field1120399'] = 'Social Skills Programmes (Other)';
+$string['field11205'] = 'Employment Skills Programmes';
+$string['field1120501'] = 'Career Development Programmes';
+$string['field1120503'] = 'Job Search Skills Programmes';
+$string['field1120505'] = 'Work Practices Programmes';
+$string['field1120599'] = 'Employment Skills Programmes (Other)';
+$string['field11299'] = 'Other Mixed Field Programmes';
+$string['field1129999'] = 'Mixed Field Programmes (Other)';
index cfa4f89..6bbb927 100644 (file)
@@ -71,11 +71,11 @@ $string['aggregationcoefextra_help'] = 'If the aggregation is \'Natural\' or \'S
 
 If the aggregation is \'Mean of grades (with extra credits)\' and the extra credit is set to a value greater than zero, the extra credit is the factor by which the grade is multiplied before adding it to the total after the computation of the mean.';
 $string['aggregationcoefextra_link'] = 'grade/aggregation';
-$string['aggregationcoefextrasum'] = 'Extra credit'; // for the form with checkboxes: Natural or Simple weighted mean
+$string['aggregationcoefextrasum'] = 'Extra credit'; // For the form with checkboxes: Natural or Simple weighted mean.
 $string['aggregationcoefextrasumabbr'] = '+';
 $string['aggregationcoefextrasum_help'] = 'If the extra credit checkbox is ticked, the grade item\'s maximum grade is not added to the category\'s maximum grade, resulting in the possibility of achieving the maximum grade (or grades over the maximum if enabled by the site administrator) in the category without having the maximum grade in all the grade items.';
 $string['aggregationcoefextrasum_link'] = 'grade/aggregation';
-$string['aggregationcoefextraweight'] = 'Extra credit weight'; // for the form with input: Mean of grades (with extra credits) only
+$string['aggregationcoefextraweight'] = 'Extra credit weight'; // For the form with input: Mean of grades (with extra credits) only.
 $string['aggregationcoefextraweight_help'] = 'If the extra credit weight is set to a value greater than zero, the grade acts as extra credit during aggregation. The number is the factor by which the grade is multiplied before adding it to the total for the computation of the mean.';
 $string['aggregationcoefextraweight_link'] = 'grade/aggregation';
 $string['aggregationcoefweight'] = 'Item weight';
@@ -251,7 +251,7 @@ $string['gradeboundary_help'] = 'This setting determines the minimum percentage
 $string['gradecategories'] = 'Grade categories';
 $string['gradecategory'] = 'Grade category';
 $string['gradecategoryonmodform'] = 'Grade category';
-$string['gradecategoryonmodform_help'] =  'This setting controls the category in which this activity\'s grades are placed in the gradebook.';
+$string['gradecategoryonmodform_help'] = 'This setting controls the category in which this activity\'s grades are placed in the gradebook.';
 $string['gradecategorysettings'] = 'Grade category settings';
 $string['gradedisplay'] = 'Grade display';
 $string['gradedisplaytype'] = 'Grade display type';
index 3b5d5c8..76c1b81 100644 (file)
@@ -98,7 +98,7 @@ $string['errorcronnoxmlrpc'] = 'XML-RPC must be enabled in order to update the r
 $string['errorhublisting'] = 'An error occurred when retrieving the hub listing from Moodle. Please try again later. ({$a})';
 $string['errorlangnotrecognized'] = 'The provided language code is unknown by Moodle. Please contact {$a}';
 $string['errorregistration'] = 'An error occurred during registration, please try again later. ({$a})';
-$string['errorunpublishcourses']= 'Due to an unexpected error, the courses could not be deleted on the hub. Try again later (recommended) or contact the hub administrator.';
+$string['errorunpublishcourses'] = 'Due to an unexpected error, the courses could not be deleted on the hub. Try again later (recommended) or contact the hub administrator.';
 $string['existingscreenshotnumber'] = '{$a} existing screenshots. You will be able to see these screenshots on this page, only once the hub administrator enables your course.';
 $string['existingscreenshots'] = 'Existing screenshots';
 $string['forceunregister'] = 'Yes, clean registration data';
index 9b92f32..9a431dc 100644 (file)
@@ -834,7 +834,7 @@ $string['frontpageformatloggedin'] = 'Front page format when logged in';
 $string['frontpagenews'] = 'News items';
 $string['frontpagesettings'] = 'Front page settings';
 $string['fulllistofcourses'] = 'All courses';
-$string['fullname'] = 'Full name'; // @deprecated - use fullnamecourse or fullnameuser or some own context specific string
+$string['fullname'] = 'Full name'; /* @deprecated - Use fullnamecourse or fullnameuser or some own context specific string. */
 $string['fullnamecourse'] = 'Course full name';
 $string['fullnamecourse_help'] = 'The full name of the course is displayed at the top of each page in the course and in the list of courses.';
 $string['fullnamedisplay'] = '{$a->firstname} {$a->lastname}';
@@ -1606,7 +1606,7 @@ $string['scalestandard_link'] = 'grade/scale';
 $string['scalestip'] = 'To create custom scales, use the \'Scales...\' link in your course administration menu.';
 $string['scalestip2'] = 'To create custom scales, click the Grades link in the course administration menu, then choose Edit, Scales.';
 $string['screenshot'] = 'Screenshot';
-$string['search'] = 'Search'; // TODO MDL-34652 rename to searchforums and move to mod_forum
+$string['search'] = 'Search'; // TODO MDL-34652 rename to searchforums and move to mod_forum.
 $string['search_help'] = 'For basic searching of one or more words anywhere in the text, just type them separated by spaces. All words longer than two characters are used.
 
 For advanced searching, press the search button without typing anything in the search box to access the advanced search form.';
@@ -1674,7 +1674,7 @@ $string['setcategorytheme'] = 'Set category theme';
 $string['setpassword'] = 'Set password';
 $string['setpasswordinstructions'] = 'Please enter and repeat your new password below, then click "Set password". <br />Your new password will be saved, and you will be logged in.';
 $string['settings'] = 'Settings';
-$string['shortname'] = 'Short name'; // @deprecated MDL-34652 - use shortnamecourse or shortnameuser or some own context specific string
+$string['shortname'] = 'Short name'; /* @deprecated MDL-34652 - Use shortnamecourse or shortnameuser or some own context specific string. */
 $string['shortnamecollisionwarning'] = '[*] = This shortname is already in use by a course and will need to be changed upon approval';
 $string['shortnamecourse'] = 'Course short name';
 $string['shortnamecourse_help'] = 'The short name of the course is displayed in the navigation and is used in the subject line of course email messages.';
index 213eaea..723b28d 100644 (file)
@@ -24,7 +24,7 @@
 
 $string['availableplugins'] = 'Available plugins';
 $string['configplagiarismplugins'] = 'Please choose the plagiarism plugin you would like to configure';
-$string['enableplagiarism'] ='Enable plagiarism plugins';
+$string['enableplagiarism'] = 'Enable plagiarism plugins';
 $string['configenableplagiarism'] = 'This will allow administrators to configure plagiarism plugins (if installed)';
 $string['manageplagiarism'] = 'Manage plagiarism plugins';
 $string['nopluginsinstalled'] = 'No plagiarism plugins are installed.';
index 845f099..60e4628 100644 (file)
@@ -32,7 +32,7 @@ $string['addplugin'] = 'Add a repository plugin';
 $string['allowexternallinks'] = 'Allow external links';
 $string['areamainfile'] = 'Main file';
 $string['coursebackup'] = 'Course backups';
-$string['pluginname'] = 'Repository plugin name'; // todo fix this, this string identifier is reserved
+$string['pluginname'] = 'Repository plugin name'; // Todo fix this, this string identifier is reserved.
 $string['pluginnamehelp'] = 'If you leave this empty the default name will be used.';
 $string['sectionbackup'] = 'Section backups';
 $string['activitybackup'] = 'Activity backup';
index 5b663e8..f8bd0d8 100644 (file)
Binary files a/lib/amd/build/form-autocomplete.min.js and b/lib/amd/build/form-autocomplete.min.js differ
index ed6ed9c..ec3fb43 100644 (file)
@@ -37,9 +37,6 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
         UP: 38
     };
 
-    /** @var {Number} closeSuggestionsTimer - integer used to cancel window.setTimeout. */
-    var closeSuggestionsTimer = null;
-
     /**
      * Make an item in the selection list "active".
      *
@@ -568,15 +565,12 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
                 createItem(options, state, originalSelect);
             }
         });
-        inputElement.on('blur focus', function(e) {
-            // We may be blurring because we have clicked on the suggestion list. We
-            // dont want to close the selection list before the click event fires, so
-            // we have to delay.
-            if (closeSuggestionsTimer) {
-                window.clearTimeout(closeSuggestionsTimer);
-            }
-            closeSuggestionsTimer = window.setTimeout(function() {
-                if (e.type == 'blur') {
+        inputElement.on('blur', function() {
+            window.setTimeout(function() {
+                // Get the current element with focus.
+                var focusElement = $(document.activeElement);
+                // Only close the menu if the input hasn't regained focus.
+                if (focusElement.attr('id') != inputElement.attr('id')) {
                     if (options.tags) {
                         createItem(options, state, originalSelect);
                     }
@@ -589,9 +583,6 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
             arrowElement.on('click', function() {
                 // Prevent the close timer, or we will open, then close the suggestions.
                 inputElement.focus();
-                if (closeSuggestionsTimer) {
-                    window.clearTimeout(closeSuggestionsTimer);
-                }
                 // Show the suggestions list.
                 updateSuggestions(options, state, inputElement.val(), originalSelect);
             });
index cdeea57..0223495 100644 (file)
@@ -15,7 +15,7 @@
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * Helper to initialise behat contexts from moodle code.
+ * Helper to get behat contexts from other contexts.
  *
  * @package    core
  * @category   test
@@ -25,8 +25,7 @@
 
 // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
 
-use Behat\Mink\Session as Session,
-    Behat\Mink\Mink as Mink;
+use \Behat\Behat\Context\BehatContext;
 
 /**
  * Helper to get behat contexts.
@@ -39,28 +38,18 @@ use Behat\Mink\Session as Session,
 class behat_context_helper {
 
     /**
-     * List of already initialized contexts.
-     *
-     * @var array
+     * @var BehatContext main behat context.
      */
-    protected static $contexts = array();
+    protected static $maincontext = false;
 
     /**
-     * @var Mink.
-     */
-    protected static $mink = false;
-
-    /**
-     * Sets the browser session.
+     * Save main behat context reference to be used for finding sub-contexts.
      *
-     * @param Session $session
+     * @param BehatContext $maincontext
      * @return void
      */
-    public static function set_session(Session $session) {
-
-        // Set mink to be able to init a context.
-        self::$mink = new Mink(array('mink' => $session));
-        self::$mink->setDefaultSessionName('mink');
+    public static function set_main_context(BehatContext $maincontext) {
+        self::$maincontext = $maincontext;
     }
 
     /**
@@ -76,36 +65,10 @@ class behat_context_helper {
      */
     public static function get($classname) {
 
-        if (!self::init_context($classname)) {
+        if (!$subcontext = self::$maincontext->getSubcontextByClassName($classname)) {
             throw coding_exception('The required "' . $classname . '" class does not exist');
         }
 
-        return self::$contexts[$classname];
+        return $subcontext;
     }
-
-    /**
-     * Initializes the required context.
-     *
-     * @throws coding_exception
-     * @param string $classname
-     * @return bool
-     */
-    protected static function init_context($classname) {
-
-        if (!empty(self::$contexts[$classname])) {
-            return true;
-        }
-
-        if (!class_exists($classname)) {
-            return false;
-        }
-
-        $instance = new $classname();
-        $instance->setMink(self::$mink);
-
-        self::$contexts[$classname] = $instance;
-
-        return true;
-    }
-
 }
index add2130..4b85386 100644 (file)
@@ -131,7 +131,7 @@ XPATH
     [./descendant::*[self::h2][normalize-space(.) = %locator%] or %locator% = 'frontpage']
 XPATH
         , 'table' => <<<XPATH
-.//table[(./@id = %locator% or contains(.//caption, %locator%) or contains(concat(' ', normalize-space(@class), ' '), %locator% ))]
+.//table[(./@id = %locator% or contains(.//caption, %locator%) or contains(.//th, %locator%) or contains(concat(' ', normalize-space(@class), ' '), %locator% ))]
 XPATH
         , 'table_row' => <<<XPATH
 .//tr[contains(normalize-space(.), %locator%) and not(.//tr[contains(normalize-space(.), %locator%)])]
index 5e81a57..9e999c2 100644 (file)
@@ -23,6 +23,8 @@
  */
 namespace core\plugininfo;
 
+use part_of_admin_tree, admin_settingpage;
+
 defined('MOODLE_INTERNAL') || die();
 
 /**
index 5ed0c73..b62cf41 100644 (file)
@@ -215,7 +215,7 @@ class core_useragent {
      * @return bool
      */
     protected function is_useragent_web_crawler() {
-        $regex = '/Googlebot|google\.com|Yahoo! Slurp|\[ZSEBOT\]|msnbot|bingbot|BingPreview|Yandex|AltaVista|Baiduspider|Teoma/';
+        $regex = '/Googlebot|google\.com|Yahoo! Slurp|\[ZSEBOT\]|msnbot|bingbot|BingPreview|Yandex|AltaVista|Baiduspider|Teoma/i';
         return (preg_match($regex, $this->useragent));
     }
 
index 8060d7f..3bf4a07 100644 (file)
@@ -906,6 +906,15 @@ $functions = array(
         'capabilities'  => '',
     ),
 
+    'core_message_delete_message' => array(
+        'classname'     => 'core_message_external',
+        'methodname'    => 'delete_message',
+        'classpath'     => 'message/externallib.php',
+        'description'   => 'Deletes a message.',
+        'type'          => 'write',
+        'capabilities'  => 'moodle/site:deleteownmessage',
+    ),
+
     // === notes related functions ===
 
     'moodle_notes_create_notes' => array(
@@ -1160,6 +1169,7 @@ $services = array(
             'core_enrol_get_enrolled_users',
             'core_enrol_get_course_enrolment_methods',
             'enrol_self_enrol_user',
+            'enrol_self_get_instance_info',
             'core_user_get_users_by_id',
             'core_webservice_get_site_info',
             'core_notes_create_notes',
@@ -1216,6 +1226,7 @@ $services = array(
             'core_completion_get_course_completion_status',
             'core_user_view_user_list',
             'core_message_mark_message_read',
+            'core_message_delete_message',
             'core_notes_view_notes',
             'mod_forum_view_forum_discussion',
             'core_user_view_user_profile',
index 3b343c0..40b21c7 100644 (file)
@@ -4606,5 +4606,8 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2015100800.01);
     }
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 9ecb9b6..d09fcc0 100644 (file)
@@ -2395,8 +2395,8 @@ function get_referer($stripquery = true) {
  * @deprecated since Moodle 3.0 use \core_useragent::is_web_crawler instead.
  */
 function is_web_crawler() {
-    debugging("is_web_crawler() has been deprecated, please use \\core_useragent\\is_web_crawler() instead.", DEBUG_DEVELOPER);
-    return core_useragent::is_crawler();
+    debugging('is_web_crawler() has been deprecated, please use core_useragent::is_web_crawler() instead.', DEBUG_DEVELOPER);
+    return core_useragent::is_web_crawler();
 }
 
 /**
index 86e2944..547bbad 100644 (file)
@@ -102,5 +102,8 @@ function xmldb_editor_atto_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 3f8efdb..63a1c85 100644 (file)
@@ -39,5 +39,8 @@ function xmldb_atto_equation_upgrade($oldversion) {
         upgrade_plugin_savepoint(true, 2015083100, 'atto', 'equation');
     }
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
\ No newline at end of file
index da400f2..41e53ad 100644 (file)
Binary files a/lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin-debug.js and b/lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin-debug.js differ
index e49012e..040eb14 100644 (file)
Binary files a/lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin-min.js and b/lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin-min.js differ
index 6cedbfa..e436da5 100644 (file)
Binary files a/lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin.js and b/lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin.js differ
index c990715..a8f9ff3 100644 (file)
@@ -27,7 +27,8 @@
             "event-outside",
             "handlebars",
             "event-custom",
-            "timers"
+            "timers",
+            "moodle-editor_atto-menu"
         ]
     },
     "moodle-editor_atto-menu": {
index 73127cd..6323f52 100644 (file)
@@ -184,5 +184,8 @@ fontselect,fontsizeselect,wrap,code,search,replace,wrap,nonbreaking,charmap,tabl
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 0998976..021ab45 100644 (file)
@@ -56,5 +56,8 @@ function xmldb_tinymce_spellchecker_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index c69fb39..426c9a2 100644 (file)
@@ -452,7 +452,7 @@ function enrol_add_course_navigation(navigation_node $coursenode, $course) {
             }
         }
         // Check role permissions
-        if (has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride','moodle/role:override', 'moodle/role:assign'), $coursecontext)) {
+        if (has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride', 'moodle/role:override'), $coursecontext)) {
             $url = new moodle_url('/admin/roles/check.php', array('contextid'=>$coursecontext->id));
             $permissionsnode->add(get_string('checkpermissions', 'role'), $url, navigation_node::TYPE_SETTING, null, 'permissions', new pix_icon('i/checkpermissions', ''));
         }
index ba89fd2..0c23431 100644 (file)
@@ -463,7 +463,7 @@ class filterobject {
      * @param bool $fullmatch
      * @param mixed $replacementphrase
      */
-    function filterobject($phrase, $hreftagbegin = '<span class="highlight">',
+    public function __construct($phrase, $hreftagbegin = '<span class="highlight">',
                                    $hreftagend = '</span>',
                                    $casesensitive = false,
                                    $fullmatch = false,
index fa15b38..f9206c4 100644 (file)
@@ -36,7 +36,7 @@ function flowplayer_send_flash_content($filename) {
     // Note: Do not use any fancy APIs here, this must work in all supported versions.
 
     // No url params.
-    if (!empty($_GET) or !empty($_POST) or !empty($_REQUEST)) {
+    if (!empty($_GET) or !empty($_POST)) {
         header("HTTP/1.1 404 Not Found");
         die;
     }
index abb73c3..8fd08cd 100644 (file)
@@ -4936,7 +4936,6 @@ function remove_course_contents($courseid, $showfeedback = true, array $options
     $oldcourse->summary          = '';
     $oldcourse->cacherev         = 0;
     $oldcourse->legacyfiles      = 0;
-    $oldcourse->enablecompletion = 0;
     if (!empty($options['keep_groups_and_groupings'])) {
         $oldcourse->defaultgroupingid = 0;
     }
index ae28067..9385451 100644 (file)
@@ -2342,6 +2342,15 @@ class global_navigation extends navigation_node {
                 }
             }
 
+            // Let plugins hook into user navigation.
+            $pluginsfunction = get_plugins_with_function('extend_navigation_user', 'lib.php');
+            foreach ($pluginsfunction as $plugintype => $plugins) {
+                if ($plugintype != 'report') {
+                    foreach ($plugins as $pluginfunction) {
+                        $pluginfunction($usernode, $user, $usercontext, $course, $coursecontext);
+                    }
+                }
+            }
         }
         return true;
     }
@@ -3971,6 +3980,7 @@ class settings_navigation extends navigation_node {
         }
 
         $modulenode = $this->add(get_string('pluginadministration', $this->page->activityname), null, self::TYPE_SETTING, null, 'modulesettings');
+        $modulenode->nodetype = navigation_node::NODETYPE_BRANCH;
         $modulenode->force_open();
 
         // Settings for the module
@@ -4026,14 +4036,12 @@ class settings_navigation extends navigation_node {
         }
 
         $function = $this->page->activityname.'_extend_settings_navigation';
-        if (!function_exists($function)) {
-            return $modulenode;
+        if (function_exists($function)) {
+            $function($this, $modulenode);
         }
 
-        $function($this, $modulenode);
-
-        // Remove the module node if there are no children
-        if (empty($modulenode->children)) {
+        // Remove the module node if there are no children.
+        if ($modulenode->children->count() <= 0) {
             $modulenode->remove();
         }
 
@@ -4307,6 +4315,17 @@ class settings_navigation extends navigation_node {
                 }
                 $dashboard->add(get_string('grades', 'grades'), $url, self::TYPE_SETTING, null, 'mygrades');
             }
+
+            // Let plugins hook into user navigation.
+            $pluginsfunction = get_plugins_with_function('extend_navigation_user', 'lib.php');
+            foreach ($pluginsfunction as $plugintype => $plugins) {
+                if ($plugintype != 'report') {
+                    foreach ($plugins as $pluginfunction) {
+                        $pluginfunction($profilenode, $user, $usercontext, $course, $coursecontext);
+                    }
+                }
+            }
+
             $usersetting = navigation_node::create(get_string('preferences', 'moodle'), $prefurl, self::TYPE_CONTAINER, null, $key);
             $dashboard->add_node($usersetting);
         } else {
@@ -4572,6 +4591,7 @@ class settings_navigation extends navigation_node {
         }
 
         $categorynode = $this->add($catcontext->get_context_name(), null, null, null, 'categorysettings');
+        $categorynode->nodetype = navigation_node::NODETYPE_BRANCH;
         $categorynode->force_open();
 
         if (can_edit_in_category($catcontext->instanceid)) {
index 3235846..99f4cb2 100644 (file)
@@ -3671,32 +3671,34 @@ EOD;
             return $str;
         }
 
-        // Print subtree
-        $str .= html_writer::start_tag('ul', array('class' => 'tabrow'. $tabobject->level));
-        $cnt = 0;
-        foreach ($tabobject->subtree as $tab) {
-            $liclass = '';
-            if (!$cnt) {
-                $liclass .= ' first';
-            }
-            if ($cnt == count($tabobject->subtree) - 1) {
-                $liclass .= ' last';
-            }
-            if ((empty($tab->subtree)) && (!empty($tab->selected))) {
-                $liclass .= ' onerow';
-            }
+        // Print subtree.
+        if ($tabobject->level == 0 || $tabobject->selected || $tabobject->activated) {
+            $str .= html_writer::start_tag('ul', array('class' => 'tabrow'. $tabobject->level));
+            $cnt = 0;
+            foreach ($tabobject->subtree as $tab) {
+                $liclass = '';
+                if (!$cnt) {
+                    $liclass .= ' first';
+                }
+                if ($cnt == count($tabobject->subtree) - 1) {
+                    $liclass .= ' last';
+                }
+                if ((empty($tab->subtree)) && (!empty($tab->selected))) {
+                    $liclass .= ' onerow';
+                }
 
-            if ($tab->selected) {
-                $liclass .= ' here selected';
-            } else if ($tab->activated) {
-                $liclass .= ' here active';
-            }
+                if ($tab->selected) {
+                    $liclass .= ' here selected';
+                } else if ($tab->activated) {
+                    $liclass .= ' here active';
+                }
 
-            // This will recursively call function render_tabobject() for each item in subtree
-            $str .= html_writer::tag('li', $this->render($tab), array('class' => trim($liclass)));
-            $cnt++;
+                // This will recursively call function render_tabobject() for each item in subtree.
+                $str .= html_writer::tag('li', $this->render($tab), array('class' => trim($liclass)));
+                $cnt++;
+            }
+            $str .= html_writer::end_tag('ul');
         }
-        $str .= html_writer::end_tag('ul');
 
         return $str;
     }
index a0e38e3..4e07072 100644 (file)
@@ -16,6 +16,8 @@ Our changes:
 * Added the following require_once() to the test files:
     global $CFG;
     require_once($CFG->dirroot . '/lib/password_compat/lib/password.php');
+* tests/PasswordHashTest.php supresses debugging from using salt in password_hash()
+  see MDL-52283
 
 Library description:
 ====================
index 31435bc..261d6df 100644 (file)
@@ -19,12 +19,12 @@ class PasswordHashTest extends PHPUnit_Framework_TestCase {
     }
 
     public function testKnownSalt() {
-        $hash = password_hash("rasmuslerdorf", PASSWORD_BCRYPT, array("cost" => 7, "salt" => "usesomesillystringforsalt"));
+        $hash = @password_hash("rasmuslerdorf", PASSWORD_BCRYPT, array("cost" => 7, "salt" => "usesomesillystringforsalt"));
         $this->assertEquals('$2y$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi', $hash);
     }
 
     public function testRawSalt() {
-        $hash = password_hash("test", PASSWORD_BCRYPT, array("salt" => "123456789012345678901" . chr(0)));
+        $hash = @password_hash("test", PASSWORD_BCRYPT, array("salt" => "123456789012345678901" . chr(0)));
         if (version_compare(PHP_VERSION, '5.5.0', '<')) {
             $this->assertEquals('$2y$10$KRGxLBS0Lxe3KBCwKxOzLexLDeu0ZfqJAKTubOfy7O/yL2hjimw3u', $hash);
         } else {
@@ -33,12 +33,12 @@ class PasswordHashTest extends PHPUnit_Framework_TestCase {
     }
 
     public function testNullBehavior() {
-        $hash = password_hash(null, PASSWORD_BCRYPT, array("salt" => "1234567890123456789012345678901234567890"));
+        $hash = @password_hash(null, PASSWORD_BCRYPT, array("salt" => "1234567890123456789012345678901234567890"));
         $this->assertEquals('$2y$10$123456789012345678901uhihPb9QpE2n03zMu9TDdvO34jDn6mO.', $hash);
     }
 
     public function testIntegerBehavior() {
-        $hash = password_hash(12345, PASSWORD_BCRYPT, array("salt" => "1234567890123456789012345678901234567890"));
+        $hash = @password_hash(12345, PASSWORD_BCRYPT, array("salt" => "1234567890123456789012345678901234567890"));
         $this->assertEquals('$2y$10$123456789012345678901ujczD5TiARVFtc68bZCAlbEg1fCIexfO', $hash);
     }    
 
index a3d7233..2321e4a 100644 (file)
@@ -131,6 +131,7 @@ class phpunit_util extends testing_util {
         }
 
         $resetdb = self::reset_database();
+        $localename = self::get_locale_name();
         $warnings = array();
 
         if ($detectchanges === true) {
@@ -163,14 +164,8 @@ class phpunit_util extends testing_util {
                 $warnings[] = 'Warning: unexpected change of $COURSE';
             }
 
-            if ($CFG->ostype === 'WINDOWS') {
-                if (setlocale(LC_TIME, 0) !== 'English_Australia.1252') {
-                    $warnings[] = 'Warning: unexpected change of locale';
-                }
-            } else {
-                if (setlocale(LC_TIME, 0) !== 'en_AU.UTF-8') {
-                    $warnings[] = 'Warning: unexpected change of locale';
-                }
+            if (setlocale(LC_TIME, 0) !== $localename) {
+                $warnings[] = 'Warning: unexpected change of locale';
             }
         }
 
@@ -262,11 +257,7 @@ class phpunit_util extends testing_util {
         core_date::phpunit_reset();
 
         // Make sure the time locale is consistent - that is Australian English.
-        if ($CFG->ostype === 'WINDOWS') {
-            setlocale(LC_TIME, 'English_Australia.1252');
-        } else {
-            setlocale(LC_TIME, 'en_AU.UTF-8');
-        }
+        setlocale(LC_TIME, $localename);
 
         // verify db writes just in case something goes wrong in reset
         if (self::$lastdbwrites != $DB->perf_get_writes()) {
@@ -362,6 +353,11 @@ class phpunit_util extends testing_util {
     public static function testing_ready_problem() {
         global $DB;
 
+        $localename = self::get_locale_name();
+        if (setlocale(LC_TIME, $localename) === false) {
+            return array(PHPUNIT_EXITCODE_CONFIGERROR, "Required locale '$localename' is not installed.");
+        }
+
         if (!self::is_test_site()) {
             // dataroot was verified in bootstrap, so it must be DB
             return array(PHPUNIT_EXITCODE_CONFIGERROR, 'Can not use database for testing, try different prefix');
@@ -798,4 +794,19 @@ class phpunit_util extends testing_util {
             self::$eventsink->add_event($event);
         }
     }
+
+    /**
+     * Gets the name of the locale for testing environment (Australian English)
+     * depending on platform environment.
+     *
+     * @return string the locale name.
+     */
+    protected static function get_locale_name() {
+        global $CFG;
+        if ($CFG->ostype === 'WINDOWS') {
+            return 'English_Australia.1252';
+        } else {
+            return 'en_AU.UTF-8';
+        }
+    }
 }
index e2c4b7f..53b64a6 100644 (file)
@@ -67,6 +67,7 @@ class flexible_table {
     var $column_suppress = array();
     var $column_nosort   = array('userpic');
     private $column_textsort = array();
+    /** @var boolean Stores if setup has already been called on this flixible table. */
     var $setup           = false;
     var $baseurl         = NULL;
     var $request         = array();
index 5df77bb..78ea809 100644 (file)
@@ -256,7 +256,7 @@ class behat_hooks extends behat_base {
         // We need the Mink session to do it and we do it only before the first scenario.
         if (self::is_first_scenario()) {
             behat_selectors::register_moodle_selectors($session);
-            behat_context_helper::set_session($session);
+            behat_context_helper::set_main_context($event->getContext()->getMainContext());
         }
 
         // Reset mink session between the scenarios.
@@ -384,6 +384,18 @@ class behat_hooks extends behat_base {
         }
     }
 
+    /**
+     * Executed after scenario having switch window to restart session.
+     * This is needed to close all extra browser windows and starting
+     * one browser window.
+     *
+     * @param ScenarioEvent $event event fired after scenario.
+     * @AfterScenario @_switch_window
+     */
+    public function after_scenario_switchwindow(ScenarioEvent $event) {
+        $this->getSession()->restart();
+    }
+
     /**
      * Getter for self::$faildumpdirname
      *
index b81c59a..5196395 100644 (file)
@@ -29,7 +29,7 @@
  * @copyright  2013 Sam Hemelryk
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-class core_useragent_testcase extends basic_testcase {
+class core_useragent_testcase extends advanced_testcase {
 
     /**
      * Restores the user agent to the default one.
@@ -1865,4 +1865,61 @@ class core_useragent_testcase extends basic_testcase {
         $expectation = isset($tests['is_web_crawler']) ? $tests['is_web_crawler'] : false;
         $this->assertSame($expectation, core_useragent::is_web_crawler());
     }
+
+    /**
+     * Regression tests for the deprecated is_web_crawler() function
+     */
+    public function test_deprecated_is_web_crawler() {
+
+        $browsers = array(
+            'Mozilla/5.0 (Windows; U; MSIE 9.0; WIndows NT 9.0; en-US))',
+            'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:18.0) Gecko/18.0 Firefox/18.0',
+            'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/412 (KHTML, like Gecko) Safari/412',
+            'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.215 Safari/534.10',
+            'Opera/9.0 (Windows NT 5.1; U; en)',
+            'Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17 –Nexus',
+            'Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5',
+        );
+        $crawlers = array(
+            // Google.
+            'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
+            'Googlebot/2.1 (+http://www.googlebot.com/bot.html)',
+            'Googlebot-Image/1.0',
+            // Yahoo.
+            'Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)',
+            // Bing.
+            'Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
+            'Mozilla/5.0 (compatible; bingbot/2.0 +http://www.bing.com/bingbot.htm)',
+            // MSN.
+            'msnbot/2.1',
+            // Yandex.
+            'Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)',
+            'Mozilla/5.0 (compatible; YandexImages/3.0; +http://yandex.com/bots)',
+            // AltaVista.
+            'AltaVista V2.0B crawler@evreka.com',
+            // ZoomSpider.
+            'ZoomSpider - wrensoft.com [ZSEBOT]',
+            // Baidu.
+            'Baiduspider+(+http://www.baidu.com/search/spider_jp.html)',
+            'Baiduspider+(+http://www.baidu.com/search/spider.htm)',
+            'BaiDuSpider',
+            // Ask.com.
+            'User-Agent: Mozilla/2.0 (compatible; Ask Jeeves/Teoma)',
+        );
+
+        foreach ($browsers as $agent) {
+            core_useragent::instance(true, $agent);
+            $this->assertSame($agent, core_useragent::get_user_agent_string());
+            $this->assertFalse(is_web_crawler());
+            $this->assertDebuggingCalled('is_web_crawler() has been deprecated, please use core_useragent::is_web_crawler() instead.',
+                DEBUG_DEVELOPER);
+        }
+        foreach ($crawlers as $agent) {
+            core_useragent::instance(true, $agent);
+            $this->assertSame($agent, core_useragent::get_user_agent_string());
+            $this->assertTrue(is_web_crawler(), "$agent should be considered a search engine");
+            $this->assertDebuggingCalled('is_web_crawler() has been deprecated, please use core_useragent::is_web_crawler() instead.',
+                DEBUG_DEVELOPER);
+        }
+    }
 }
index f2a60e3..899b088 100644 (file)
@@ -246,6 +246,24 @@ class core_weblib_testcase extends advanced_testcase {
         $this->assertSame($strurl, $url->out(false));
     }
 
+    /**
+     * Test set good scheme on Moodle URL objects.
+     */
+    public function test_moodle_url_set_good_scheme() {
+        $url = new moodle_url('http://moodle.org/foo/bar');
+        $url->set_scheme('myscheme');
+        $this->assertSame('myscheme://moodle.org/foo/bar', $url->out());
+    }
+
+    /**
+     * Test set bad scheme on Moodle URL objects.
+     */
+    public function test_moodle_url_set_bad_scheme() {
+        $url = new moodle_url('http://moodle.org/foo/bar');
+        $this->setExpectedException('coding_exception');
+        $url->set_scheme('not a valid $ scheme');
+    }
+
     public function test_moodle_url_round_trip_array_params() {
         $strurl = 'http://example.com/?a%5B1%5D=1&a%5B2%5D=2';
         $url = new moodle_url($strurl);
index 7b5641f..5a732f1 100644 (file)
@@ -1,6 +1,13 @@
 This files describes API changes in core libraries and APIs,
 information provided here is intended especially for developers.
 
+=== 3.1 ===
+
+* Plugins can extend the navigation for user by declaring the following callback:
+  <frankenstyle>_extend_navigation_user(navigation_node $parentnode, stdClass $user,
+                                        context_user $context, stdClass $course,
+                                        context_course $coursecontext)
+
 === 3.0 ===
 
 * Minify updated to 2.2.1
@@ -151,6 +158,7 @@ information provided here is intended especially for developers.
   line interface scripts.
 * External function core_course_external::get_course_contents returned parameter "name" has been changed to PARAM_RAW,
   this is because the new external_format_string function may return raw data if the global moodlewssettingraw parameter is used.
+* Function is_web_crawler() has been deprecated, please use core_useragent::is_web_crawler() instead.
 
 === 2.9.1 ===
 
index b7e67e5..aed1cb4 100644 (file)
@@ -672,6 +672,20 @@ class moodle_url {
         }
     }
 
+    /**
+     * Sets the scheme for the URI (the bit before ://)
+     *
+     * @param string $scheme
+     */
+    public function set_scheme($scheme) {
+        // See http://www.ietf.org/rfc/rfc3986.txt part 3.1.
+        if (preg_match('/^[a-zA-Z][a-zA-Z0-9+.-]*$/', $scheme)) {
+            $this->scheme = $scheme;
+        } else {
+            throw new coding_exception('Bad URL scheme.');
+        }
+    }
+
     /**
      * Sets the url slashargument value.
      *
index 962216f..35aef7e 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 require_once("$CFG->libdir/externallib.php");
+require_once($CFG->dirroot . "/message/lib.php");
 
 /**
  * Message external functions
@@ -69,7 +70,6 @@ class core_message_external extends external_api {
      */
     public static function send_instant_messages($messages = array()) {
         global $CFG, $USER, $DB;
-        require_once($CFG->dirroot . "/message/lib.php");
 
         // Check if messaging is enabled.
         if (!$CFG->messaging) {
@@ -652,7 +652,6 @@ class core_message_external extends external_api {
     public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true,
                                         $newestfirst = true, $limitfrom = 0, $limitnum = 0) {
         global $CFG, $USER;
-        require_once($CFG->dirroot . "/message/lib.php");
 
         $warnings = array();
 
@@ -853,7 +852,6 @@ class core_message_external extends external_api {
      */
     public static function get_blocked_users($userid) {
         global $CFG, $USER, $PAGE;
-        require_once($CFG->dirroot . "/message/lib.php");
 
         // Warnings array, it can be empty at the end but is mandatory.
         $warnings = array();
@@ -957,7 +955,6 @@ class core_message_external extends external_api {
      */
     public static function mark_message_read($messageid, $timeread) {
         global $CFG, $DB, $USER;
-        require_once($CFG->dirroot . "/message/lib.php");
 
         // Check if private messaging between users is allowed.
         if (empty($CFG->messaging)) {
@@ -1008,6 +1005,90 @@ class core_message_external extends external_api {
         );
     }
 
+    /**
+     * Returns description of method parameters
+     *
+     * @return external_function_parameters
+     * @since 3.1
+     */
+    public static function delete_message_parameters() {
+        return new external_function_parameters(
+            array(
+                'messageid' => new external_value(PARAM_INT, 'The message id'),
+                'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the message for'),
+                'read' => new external_value(PARAM_BOOL, 'If is a message read', VALUE_DEFAULT, true)
+            )
+        );
+    }
+
+    /**
+     * Deletes a message
+     *
+     * @param  int $messageid the message id
+     * @param  int $userid the user id of who we want to delete the message for
+     * @param  bool $read if is a message read (default to true)
+     * @return external_description
+     * @throws moodle_exception
+     * @since 3.1
+     */
+    public static function delete_message($messageid, $userid, $read = true) {
+        global $CFG, $DB;
+
+        // Check if private messaging between users is allowed.
+        if (empty($CFG->messaging)) {
+            throw new moodle_exception('disabled', 'message');
+        }
+
+        // Warnings array, it can be empty at the end but is mandatory.
+        $warnings = array();
+
+        // Validate params.
+        $params = array(
+            'messageid' => $messageid,
+            'userid' => $userid,
+            'read' => $read
+        );
+        $params = self::validate_parameters(self::delete_message_parameters(), $params);
+
+        // Validate context.
+        $context = context_system::instance();
+        self::validate_context($context);
+
+        $messagestable = $params['read'] ? 'message_read' : 'message';
+        $message = $DB->get_record($messagestable, array('id' => $params['messageid']), '*', MUST_EXIST);
+
+        $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
+        core_user::require_active_user($user);
+
+        $status = false;
+        if (message_can_delete_message($message, $user->id)) {
+            $status = message_delete_message($message, $user->id);;
+        } else {
+            throw new moodle_exception('You do not have permission to delete this message');
+        }
+
+        $results = array(
+            'status' => $status,
+            'warnings' => $warnings
+        );
+        return $results;
+    }
+
+    /**
+     * Returns description of method result value
+     *
+     * @return external_description
+     * @since 3.1
+     */
+    public static function delete_message_returns() {
+        return new external_single_structure(
+            array(
+                'status' => new external_value(PARAM_BOOL, 'True if the message was deleted, false otherwise'),
+                'warnings' => new external_warnings()
+            )
+        );
+    }
+
 }
 
 /**
index a8178e7..4d9e1d4 100644 (file)
@@ -60,6 +60,9 @@ function xmldb_message_email_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
 
index 80d88a1..a42641f 100644 (file)
@@ -60,6 +60,9 @@ function xmldb_message_jabber_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
 
index df7ff9a..50353b6 100644 (file)
@@ -60,6 +60,9 @@ function xmldb_message_popup_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
 
index c46828c..dff81e4 100644 (file)
@@ -697,4 +697,105 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
 
     }
 
+    /**
+     * Test delete_message.
+     */
+    public function test_delete_message() {
+        global $DB;
+        $this->resetAfterTest(true);
+
+        $user1 = self::getDataGenerator()->create_user();
+        $user2 = self::getDataGenerator()->create_user();
+        $user3 = self::getDataGenerator()->create_user();
+        $user4 = self::getDataGenerator()->create_user();
+
+        // Login as user1.
+        $this->setUser($user1);
+        $this->assertEquals(array(), core_message_external::create_contacts(array($user2->id, $user3->id)));
+
+        // User user1 does not interchange messages with user3.
+        $m1to2 = message_post_message($user1, $user2, 'some random text 1', FORMAT_MOODLE);
+        $m2to3 = message_post_message($user2, $user3, 'some random text 3', FORMAT_MOODLE);
+        $m3to2 = message_post_message($user3, $user2, 'some random text 4', FORMAT_MOODLE);
+        $m3to4 = message_post_message($user3, $user4, 'some random text 4', FORMAT_MOODLE);
+
+        // Retrieve all messages sent by user2 (they are currently unread).
+        $lastmessages = message_get_messages($user1->id, $user2->id, 0, false);
+
+        // Delete a message not read, as a user from.
+        $result = core_message_external::delete_message($m1to2, $user1->id, false);
+        $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
+        $this->assertTrue($result['status']);
+        $this->assertCount(0, $result['warnings']);
+        $deletedmessage = $DB->get_record('message', array('id' => $m1to2));
+        $this->assertNotEquals(0, $deletedmessage->timeuserfromdeleted);
+
+        // Try to delete the same message again.
+        $result = core_message_external::delete_message($m1to2, $user1->id, false);
+        $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
+        $this->assertFalse($result['status']);
+
+        // Try to delete a message that does not belong to me.
+        try {
+            $messageid = core_message_external::delete_message($m2to3, $user3->id, false);
+            $this->fail('Exception expected due invalid messageid.');
+        } catch (moodle_exception $e) {
+            $this->assertEquals('You do not have permission to delete this message', $e->errorcode);
+        }
+
+        $this->setUser($user3);
+        // Delete a message not read, as a user to.
+        $result = core_message_external::delete_message($m2to3, $user3->id, false);
+        $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
+        $this->assertTrue($result['status']);
+        $this->assertCount(0, $result['warnings']);
+        $deletedmessage = $DB->get_record('message', array('id' => $m2to3));
+        $this->assertNotEquals(0, $deletedmessage->timeusertodeleted);
+
+        // Delete a message read.
+        $message = $DB->get_record('message', array('id' => $m3to2));
+        $messageid = message_mark_message_read($message, time());
+        $result = core_message_external::delete_message($messageid, $user3->id);
+        $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
+        $this->assertTrue($result['status']);
+        $this->assertCount(0, $result['warnings']);
+        $deletedmessage = $DB->get_record('message_read', array('id' => $messageid));
+        $this->assertNotEquals(0, $deletedmessage->timeuserfromdeleted);
+
+        // Invalid message ids.
+        try {
+            $result = core_message_external::delete_message(-1, $user1->id);
+            $this->fail('Exception expected due invalid messageid.');
+        } catch (dml_missing_record_exception $e) {
+            $this->assertEquals('invalidrecord', $e->errorcode);
+        }
+
+        // Invalid user.
+        try {
+            $result = core_message_external::delete_message($m1to2, -1, false);
+            $this->fail('Exception expected due invalid user.');
+        } catch (moodle_exception $e) {
+            $this->assertEquals('invaliduser', $e->errorcode);
+        }
+
+        // Not active user.
+        delete_user($user2);
+        try {
+            $result = core_message_external::delete_message($m1to2, $user2->id, false);
+            $this->fail('Exception expected due invalid user.');
+        } catch (moodle_exception $e) {
+            $this->assertEquals('userdeleted', $e->errorcode);
+        }
+
+        // Now, as an admin, try to delete any message.
+        $this->setAdminUser();
+        $result = core_message_external::delete_message($m3to4, $user4->id, false);
+        $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
+        $this->assertTrue($result['status']);
+        $this->assertCount(0, $result['warnings']);
+        $deletedmessage = $DB->get_record('message', array('id' => $m3to4));
+        $this->assertNotEquals(0, $deletedmessage->timeusertodeleted);
+
+    }
+
 }
index 2c51e85..2debb16 100644 (file)
@@ -646,5 +646,8 @@ function xmldb_assign_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 0b39697..30d0376 100644 (file)
@@ -44,19 +44,25 @@ class mod_assign_extension_form extends moodleform {
      */
     public function definition() {
         $mform = $this->_form;
+        $params = $this->_customdata;
 
-        list($coursemoduleid, $userid, $batchusers, $instance, $data) = $this->_customdata;
         // Instance variable is used by the form validation function.
+        $instance = $params['instance'];
         $this->instance = $instance;
 
-        if ($batchusers) {
-            $listusersmessage = get_string('grantextensionforusers', 'assign', count(explode(',', $batchusers)));
-            $mform->addElement('static', 'applytoselectedusers', '', $listusersmessage);
+        if (!empty($params['userscount'])) {
+            $listusersmessage = get_string('grantextensionforusers', 'assign', $params['userscount']);
+            $mform->addElement('header', 'general', $listusersmessage);
+            $mform->addElement('static', 'userslist', get_string('selectedusers', 'assign'), $params['usershtml']);
+        } else {
+            $mform->addElement('static', 'userslist', '', $params['usershtml']);
         }
         if ($instance->allowsubmissionsfromdate) {
             $mform->addElement('static', 'allowsubmissionsfromdate', get_string('allowsubmissionsfromdate', 'assign'),
                                userdate($instance->allowsubmissionsfromdate));
         }
+
+        $finaldate = 0;
         if ($instance->duedate) {
             $mform->addElement('static', 'duedate', get_string('duedate', 'assign'), userdate($instance->duedate));
             $finaldate = $instance->duedate;
@@ -68,19 +74,17 @@ class mod_assign_extension_form extends moodleform {
         $mform->addElement('date_time_selector', 'extensionduedate',
                            get_string('extensionduedate', 'assign'), array('optional'=>true));
         $mform->setDefault('extensionduedate', $finaldate);
-        $mform->addElement('hidden', 'id', $coursemoduleid);
+
+        $mform->addElement('hidden', 'id');
         $mform->setType('id', PARAM_INT);
-        $mform->addElement('hidden', 'userid', $userid);
+        $mform->addElement('hidden', 'userid');
         $mform->setType('userid', PARAM_INT);
-        $mform->addElement('hidden', 'selectedusers', $batchusers);
+        $mform->addElement('hidden', 'selectedusers');
         $mform->setType('selectedusers', PARAM_SEQUENCE);
         $mform->addElement('hidden', 'action', 'saveextension');
         $mform->setType('action', PARAM_ALPHA);
-        $this->add_action_buttons(true, get_string('savechanges', 'assign'));
 
-        if ($data) {
-            $this->set_data($data);
-        }
+        $this->add_action_buttons(true, get_string('savechanges', 'assign'));
     }
 
     /**
index 7255de7..30cb8e9 100644 (file)
@@ -50,5 +50,8 @@ function xmldb_assignfeedback_comments_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index d2742a2..89d6e74 100644 (file)
@@ -76,5 +76,8 @@ function xmldb_assignfeedback_editpdf_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 565dd2d..286c0f3 100644 (file)
Binary files a/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-debug.js and b/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-debug.js differ
index e5e4732..28d56f5 100644 (file)
Binary files a/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-min.js and b/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-min.js differ
index 565dd2d..286c0f3 100644 (file)
Binary files a/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor.js and b/mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor.js differ
index 3ccb9ac..5415add 100644 (file)
@@ -170,8 +170,8 @@ Y.extend(ANNOTATION, Y.Base, {
      */
     draw_highlight : function() {
         var bounds,
-            drawingregion = Y.one(SELECTOR.DRAWINGREGION),
-            offsetcanvas = Y.one(SELECTOR.DRAWINGCANVAS).getXY(),
+            drawingregion = this.editor.get_dialogue_element(SELECTOR.DRAWINGREGION),
+            offsetcanvas = this.editor.get_dialogue_element(SELECTOR.DRAWINGCANVAS).getXY(),
             shape;
 
         if (this.editor.currentannotation === this) {
index df1c0bf..d4597ec 100644 (file)
@@ -42,7 +42,7 @@ Y.extend(ANNOTATIONSTAMP, M.assignfeedback_editpdf.annotation, {
      */
     draw : function() {
         var drawable = new M.assignfeedback_editpdf.drawable(this.editor),
-            drawingregion = Y.one(SELECTOR.DRAWINGREGION),
+            drawingregion = this.editor.get_dialogue_element(SELECTOR.DRAWINGREGION),
             node,
             position;
 
@@ -84,7 +84,7 @@ Y.extend(ANNOTATIONSTAMP, M.assignfeedback_editpdf.annotation, {
     draw_current_edit : function(edit) {
         var bounds = new M.assignfeedback_editpdf.rect(),
             drawable = new M.assignfeedback_editpdf.drawable(this.editor),
-            drawingregion = Y.one(SELECTOR.DRAWINGREGION),
+            drawingregion = this.editor.get_dialogue_element(SELECTOR.DRAWINGREGION),
             node,
             position;
 
index c37c8ca..bdb96f9 100644 (file)
@@ -159,7 +159,7 @@ var COMMENT = function(editor, gradeid, pageno, x, y, width, colour, rawtext) {
     this.draw = function(focus) {
         var drawable = new M.assignfeedback_editpdf.drawable(this.editor),
             node,
-            drawingregion = Y.one(SELECTOR.DRAWINGREGION),
+            drawingregion = this.editor.get_dialogue_element(SELECTOR.DRAWINGREGION),
             container,
             menu,
             position,
index 0dece81..73b2657 100644 (file)
@@ -52,7 +52,7 @@ Y.extend(COMMENTSEARCH, M.core.dialogue, {
         commentlist = Y.Node.create('<ul role="menu" class="assignfeedback_editpdf_menu"/>');
         container.append(commentlist);
 
-        commentfilter.on('keyup', this.filter_search_comments, null, this);
+        commentfilter.on('keyup', this.filter_search_comments, this);
         commentlist.delegate('click', this.focus_on_comment, 'a', this);
         commentlist.delegate('key', this.focus_on_comment, 'enter,space', 'a', this);
 
@@ -71,10 +71,12 @@ Y.extend(COMMENTSEARCH, M.core.dialogue, {
     filter_search_comments : function() {
         var filternode,
             commentslist,
-            filtertext;
+            filtertext,
+            dialogueid;
 
-        filternode = Y.one(SELECTOR.SEARCHFILTER);
-        commentslist = Y.one(SELECTOR.SEARCHCOMMENTSLIST);
+        dialogueid = this.get('id');
+        filternode = Y.one('#' + dialogueid + SELECTOR.SEARCHFILTER);
+        commentslist = Y.one('#' + dialogueid + SELECTOR.SEARCHCOMMENTSLIST);
 
         filtertext = filternode.get('value');
 
index 3daec87..21e368c 100644 (file)
@@ -100,7 +100,7 @@ var DRAWABLE = function(editor) {
     this.store_position = function(container, x, y) {
         var drawingregion, scrollx, scrolly;
 
-        drawingregion = Y.one(SELECTOR.DRAWINGREGION);
+        drawingregion = this.editor.get_dialogue_element(SELECTOR.DRAWINGREGION);
         scrollx = parseInt(drawingregion.get('scrollLeft'), 10);
         scrolly = parseInt(drawingregion.get('scrollTop'), 10);
         container.setData('x', x + scrollx);
index 33c915a..4f38c87 100644 (file)
@@ -219,7 +219,7 @@ EDITOR.prototype = {
         var button, currenttoolnode, imgurl;
 
         // Initalise the colour buttons.
-        button = Y.one(SELECTOR.COMMENTCOLOURBUTTON);
+        button = this.get_dialogue_element(SELECTOR.COMMENTCOLOURBUTTON);
 
         imgurl = M.util.image_url('background_colour_' + this.currentedit.commentcolour, 'assignfeedback_editpdf');
         button.one('img').setAttribute('src', imgurl);
@@ -230,15 +230,15 @@ EDITOR.prototype = {
             button.one('img').setStyle('borderStyle', 'solid');
         }
 
-        button = Y.one(SELECTOR.ANNOTATIONCOLOURBUTTON);
+        button = this.get_dialogue_element(SELECTOR.ANNOTATIONCOLOURBUTTON);
         imgurl = M.util.image_url('colour_' + this.currentedit.annotationcolour, 'assignfeedback_editpdf');
         button.one('img').setAttribute('src', imgurl);
 
-        currenttoolnode = Y.one(TOOLSELECTOR[this.currentedit.tool]);
+        currenttoolnode = this.get_dialogue_element(TOOLSELECTOR[this.currentedit.tool]);
         currenttoolnode.addClass('assignfeedback_editpdf_selectedbutton');
         currenttoolnode.setAttribute('aria-pressed', 'true');
 
-        button = Y.one(SELECTOR.STAMPSBUTTON);
+        button = this.get_dialogue_element(SELECTOR.STAMPSBUTTON);
         button.one('img').setAttrs({'src': this.get_stamp_image_url(this.currentedit.stamp),
                                     'height': '16',
                                     'width': '16'});
@@ -249,7 +249,7 @@ EDITOR.prototype = {
      * @method get_canvas_bounds
      */
     get_canvas_bounds : function() {
-        var canvas = Y.one(SELECTOR.DRAWINGCANVAS),
+        var canvas = this.get_dialogue_element(SELECTOR.DRAWINGCANVAS),
             offsetcanvas = canvas.getXY(),
             offsetleft = offsetcanvas[0],
             offsettop = offsetcanvas[1],
@@ -308,12 +308,12 @@ EDITOR.prototype = {
             // Add custom class for styling.
             this.dialogue.get('boundingBox').addClass(CSS.DIALOGUE);
 
-            this.loadingicon = Y.one(SELECTOR.LOADINGICON);
+            this.loadingicon = this.get_dialogue_element(SELECTOR.LOADINGICON);
 
-            drawingcanvas = Y.one(SELECTOR.DRAWINGCANVAS);
-            this.graphic = new Y.Graphic({render : SELECTOR.DRAWINGCANVAS});
+            drawingcanvas = this.get_dialogue_element(SELECTOR.DRAWINGCANVAS);
+            this.graphic = new Y.Graphic({render : drawingcanvas});
 
-            drawingregion = Y.one(SELECTOR.DRAWINGREGION);
+            drawingregion = this.get_dialogue_element(SELECTOR.DRAWINGREGION);
             drawingregion.on('scroll', this.move_canvas, this);
 
             if (!this.get('readonly')) {
@@ -393,7 +393,7 @@ EDITOR.prototype = {
                             var pagetotal = this.get('pagetotal');
 
                             // Update the progress bar.
-                            var progressbarcontainer = Y.one(SELECTOR.PROGRESSBARCONTAINER);
+                            var progressbarcontainer = this.get_dialogue_element(SELECTOR.PROGRESSBARCONTAINER);
                             var progressbar = progressbarcontainer.one('.bar');
                             if (progressbar) {
                                 // Calculate progress.
@@ -520,7 +520,7 @@ EDITOR.prototype = {
             picker,
             filename;
 
-        searchcommentsbutton = Y.one(SELECTOR.SEARCHCOMMENTSBUTTON);
+        searchcommentsbutton = this.get_dialogue_element(SELECTOR.SEARCHCOMMENTSBUTTON);
         searchcommentsbutton.on('click', this.open_search_comments, this);
         searchcommentsbutton.on('key', this.open_search_comments, 'down:13', this);
 
@@ -529,7 +529,7 @@ EDITOR.prototype = {
         }
         // Setup the tool buttons.
         Y.each(TOOLSELECTOR, function(selector, tool) {
-            toolnode = Y.one(selector);
+            toolnode = this.get_dialogue_element(selector);
             toolnode.on('click', this.handle_tool_button, this, tool);
             toolnode.on('key', this.handle_tool_button, 'down:13', this, tool);
             toolnode.setAttribute('aria-pressed', 'false');
@@ -537,7 +537,7 @@ EDITOR.prototype = {
 
         // Set the default tool.
 
-        commentcolourbutton = Y.one(SELECTOR.COMMENTCOLOURBUTTON);
+        commentcolourbutton = this.get_dialogue_element(SELECTOR.COMMENTCOLOURBUTTON);
         picker = new M.assignfeedback_editpdf.colourpicker({
             buttonNode: commentcolourbutton,
             colours: COMMENTCOLOUR,
@@ -553,7 +553,7 @@ EDITOR.prototype = {
             context: this
         });
 
-        annotationcolourbutton = Y.one(SELECTOR.ANNOTATIONCOLOURBUTTON);
+        annotationcolourbutton = this.get_dialogue_element(SELECTOR.ANNOTATIONCOLOURBUTTON);
         picker = new M.assignfeedback_editpdf.colourpicker({
             buttonNode: annotationcolourbutton,
             iconprefix: 'colour_',
@@ -575,11 +575,11 @@ EDITOR.prototype = {
 
         stampfiles = this.get('stampfiles');
         if (stampfiles.length <= 0) {
-            Y.one(TOOLSELECTOR.stamp).ancestor().hide();
+            this.get_dialogue_element(TOOLSELECTOR.stamp).ancestor().hide();
         } else {
             filename = stampfiles[0].substr(stampfiles[0].lastIndexOf('/') + 1);
             this.currentedit.stamp = filename;
-            currentstampbutton = Y.one(SELECTOR.STAMPSBUTTON);
+            currentstampbutton = this.get_dialogue_element(SELECTOR.STAMPSBUTTON);
 
             picker = new M.assignfeedback_editpdf.stamppicker({
                 buttonNode: currentstampbutton,
@@ -612,7 +612,7 @@ EDITOR.prototype = {
         e.preventDefault();
 
         // Change style of the pressed button.
-        currenttoolnode = Y.one(TOOLSELECTOR[this.currentedit.tool]);
+        currenttoolnode = this.get_dialogue_element(TOOLSELECTOR[this.currentedit.tool]);
         currenttoolnode.removeClass('assignfeedback_editpdf_selectedbutton');
         currenttoolnode.setAttribute('aria-pressed', 'false');
         this.currentedit.tool = tool;
@@ -673,6 +673,15 @@ EDITOR.prototype = {
         return drawable;
     },
 
+    /**
+     * Find an element within the dialogue.
+     * @protected
+     * @method get_dialogue_element
+     */
+    get_dialogue_element : function(selector) {
+        return this.dialogue.get('boundingBox').one(selector);
+    },
+
     /**
      * Redraw the active edit.
      * @protected
@@ -693,7 +702,7 @@ EDITOR.prototype = {
      */
     edit_start : function(e) {
         e.preventDefault();
-        var canvas = Y.one(SELECTOR.DRAWINGCANVAS),
+        var canvas = this.get_dialogue_element(SELECTOR.DRAWINGCANVAS),
             offset = canvas.getXY(),
             scrolltop = canvas.get('docScrollY'),
             scrollleft = canvas.get('docScrollX'),
@@ -764,7 +773,7 @@ EDITOR.prototype = {
     edit_move : function(e) {
         e.preventDefault();
         var bounds = this.get_canvas_bounds(),
-            canvas = Y.one(SELECTOR.DRAWINGCANVAS),
+            canvas = this.get_dialogue_element(SELECTOR.DRAWINGCANVAS),
             clientpoint = new M.assignfeedback_editpdf.point(e.clientX + canvas.get('docScrollX'),
                                                              e.clientY + canvas.get('docScrollY')),
             point = this.get_canvas_coordinates(clientpoint);
@@ -861,7 +870,7 @@ EDITOR.prototype = {
         if (drawregionheight < 100) {
             drawregionheight = 100;
         }
-        drawingregion = Y.one(SELECTOR.DRAWINGREGION);
+        drawingregion = this.get_dialogue_element(SELECTOR.DRAWINGREGION);
         drawingregion.setStyle('maxHeight', drawregionheight +'px');
         this.redraw();
         return true;
@@ -921,7 +930,8 @@ EDITOR.prototype = {
                         if (jsondata.error) {
                             return new M.core.ajaxException(jsondata);
                         }
-                        Y.one(SELECTOR.UNSAVEDCHANGESDIV).addClass('haschanges');
+                        Y.one('#' + this.get('linkid')).siblings(SELECTOR.UNSAVEDCHANGESDIV)
+                            .item(0).addClass('haschanges');
                     } catch (e) {
                         return new M.core.exception(e);
                     }
@@ -985,13 +995,13 @@ EDITOR.prototype = {
      * @method change_page
      */
     change_page : function() {
-        var drawingcanvas = Y.one(SELECTOR.DRAWINGCANVAS),
+        var drawingcanvas = this.get_dialogue_element(SELECTOR.DRAWINGCANVAS),
             page,
             previousbutton,
             nextbutton;
 
-        previousbutton = Y.one(SELECTOR.PREVIOUSBUTTON);
-        nextbutton = Y.one(SELECTOR.NEXTBUTTON);
+        previousbutton = this.get_dialogue_element(SELECTOR.PREVIOUSBUTTON);
+        nextbutton = this.get_dialogue_element(SELECTOR.NEXTBUTTON);
 
         if (this.currentpage > 0) {
             previousbutton.removeAttribute('disabled');
@@ -1011,7 +1021,7 @@ EDITOR.prototype = {
         drawingcanvas.setStyle('height', page.height + 'px');
 
         // Update page select.
-        Y.one(SELECTOR.PAGESELECT).set('value', this.currentpage);
+        this.get_dialogue_element(SELECTOR.PAGESELECT).set('value', this.currentpage);
 
         this.resize(); // Internally will call 'redraw', after checking the dialogue size.
     },
@@ -1029,7 +1039,7 @@ EDITOR.prototype = {
             previousbutton,
             nextbutton;
 
-        pageselect = Y.one(SELECTOR.PAGESELECT);
+        pageselect = this.get_dialogue_element(SELECTOR.PAGESELECT);
 
         var options = pageselect.all('option');
         if (options.size() <= 1) {
@@ -1046,8 +1056,8 @@ EDITOR.prototype = {
             this.change_page();
         }, this);
 
-        previousbutton = Y.one(SELECTOR.PREVIOUSBUTTON);
-        nextbutton = Y.one(SELECTOR.NEXTBUTTON);
+        previousbutton = this.get_dialogue_element(SELECTOR.PREVIOUSBUTTON);
+        nextbutton = this.get_dialogue_element(SELECTOR.NEXTBUTTON);
 
         previousbutton.on('click', this.previous_page, this);
         previousbutton.on('key', this.previous_page, 'down:13', this);
@@ -1091,7 +1101,7 @@ EDITOR.prototype = {
     move_canvas: function() {
         var drawingregion, x, y, i;
 
-        drawingregion = Y.one(SELECTOR.DRAWINGREGION);
+        drawingregion = this.get_dialogue_element(SELECTOR.DRAWINGREGION);
         x = parseInt(drawingregion.get('scrollLeft'), 10);
         y = parseInt(drawingregion.get('scrollTop'), 10);
 
index 7eab77e..b3f6980 100644 (file)
@@ -24,23 +24,23 @@ var AJAXBASE = M.cfg.wwwroot + '/mod/assign/feedback/editpdf/ajax.php',
         DIALOGUE : 'assignfeedback_editpdf_widget'
     },
     SELECTOR = {
-        PREVIOUSBUTTON : '.' + CSS.DIALOGUE + ' .navigate-previous-button',
-        NEXTBUTTON : '.' + CSS.DIALOGUE + ' .navigate-next-button',
-        SEARCHCOMMENTSBUTTON : '.' + CSS.DIALOGUE + ' .searchcommentsbutton',
+        PREVIOUSBUTTON :  '.navigate-previous-button',
+        NEXTBUTTON :  ' .navigate-next-button',
+        SEARCHCOMMENTSBUTTON : '.searchcommentsbutton',
         SEARCHFILTER : '.assignfeedback_editpdf_commentsearch input',
         SEARCHCOMMENTSLIST : '.assignfeedback_editpdf_commentsearch ul',
-        PAGESELECT : '.' + CSS.DIALOGUE + ' .navigate-page-select',
-        LOADINGICON : '.' + CSS.DIALOGUE + ' .loading',
-        PROGRESSBARCONTAINER : '.' + CSS.DIALOGUE + ' .progress-info.progress-striped',
-        DRAWINGREGION : '.' + CSS.DIALOGUE + ' .drawingregion',
-        DRAWINGCANVAS : '.' + CSS.DIALOGUE + ' .drawingcanvas',
-        SAVE : '.' + CSS.DIALOGUE + ' .savebutton',
-        COMMENTCOLOURBUTTON : '.' + CSS.DIALOGUE + ' .commentcolourbutton',
-        COMMENTMENU : ' .commentdrawable a',
-        ANNOTATIONCOLOURBUTTON : '.' + CSS.DIALOGUE + ' .annotationcolourbutton',
-        DELETEANNOTATIONBUTTON : '.' + CSS.DIALOGUE + ' .deleteannotationbutton',
+        PAGESELECT : '.navigate-page-select',
+        LOADINGICON : '.loading',
+        PROGRESSBARCONTAINER : '.progress-info.progress-striped',
+        DRAWINGREGION : '.drawingregion',
+        DRAWINGCANVAS : '.drawingcanvas',
+        SAVE : '.savebutton',
+        COMMENTCOLOURBUTTON : '.commentcolourbutton',
+        COMMENTMENU : '.commentdrawable a',
+        ANNOTATIONCOLOURBUTTON :  '.annotationcolourbutton',
+        DELETEANNOTATIONBUTTON : '.deleteannotationbutton',
         UNSAVEDCHANGESDIV : '.assignfeedback_editpdf_unsavedchanges',
-        STAMPSBUTTON : '.' + CSS.DIALOGUE + ' .currentstampbutton',
+        STAMPSBUTTON : '.currentstampbutton',
         DIALOGUE : '.' + CSS.DIALOGUE
     },
     SELECTEDBORDERCOLOUR = 'rgba(200, 200, 255, 0.9)',
@@ -64,13 +64,13 @@ var AJAXBASE = M.cfg.wwwroot + '/mod/assign/feedback/editpdf/ajax.php',
     },
     CLICKTIMEOUT = 300,
     TOOLSELECTOR = {
-        'comment': '.' + CSS.DIALOGUE + ' .commentbutton',
-        'pen': '.' + CSS.DIALOGUE + ' .penbutton',
-        'line': '.' + CSS.DIALOGUE + ' .linebutton',
-        'rectangle': '.' + CSS.DIALOGUE + ' .rectanglebutton',
-        'oval': '.' + CSS.DIALOGUE + ' .ovalbutton',
-        'stamp': '.' + CSS.DIALOGUE + ' .stampbutton',
-        'select': '.' + CSS.DIALOGUE + ' .selectbutton',
-        'highlight': '.' + CSS.DIALOGUE + ' .highlightbutton'
+        'comment': '.commentbutton',
+        'pen': '.penbutton',
+        'line': '.linebutton',
+        'rectangle': '.rectanglebutton',
+        'oval': '.ovalbutton',
+        'stamp': '.stampbutton',
+        'select': '.selectbutton',
+        'highlight': '.highlightbutton'
     },
     STROKEWEIGHT = 4;
index 5379fad..1f50fac 100644 (file)
@@ -50,5 +50,8 @@ function xmldb_assignfeedback_file_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
index 6ffecb8..ca436bb 100644 (file)
@@ -828,7 +828,8 @@ class assign_grading_table extends table_sql implements renderable {
                                             'mod_assign');
             $urlparams = array('id' => $this->assignment->get_course_module()->id,
                                'rownum'=>$this->rownum,
-                               'action'=>'grade');
+                               'action' => 'grade',
+                               'useridlistid' => $this->assignment->get_useridlist_key_id());
             $url = new moodle_url('/mod/assign/view.php', $urlparams);
             $link = $this->output->action_link($url, $icon);
             $grade .= $link . $separator;
@@ -972,7 +973,7 @@ class assign_grading_table extends table_sql implements renderable {
         }
 
         if ($this->is_downloading()) {
-            $o = strip_tags(str_replace('</div>', "\n", $o));
+            $o = strip_tags(rtrim(str_replace('</div>', ' - ', $o), '- '));
         }
 
         return $o;
@@ -993,7 +994,8 @@ class assign_grading_table extends table_sql implements renderable {
 
         $urlparams = array('id'=>$this->assignment->get_course_module()->id,
                            'rownum'=>$this->rownum,
-                           'action'=>'grade');
+                           'action' => 'grade',
+                           'useridlistid' => $this->assignment->get_useridlist_key_id());
         $url = new moodle_url('/mod/assign/view.php', $urlparams);
         $noimage = null;
 
@@ -1396,4 +1398,16 @@ class assign_grading_table extends table_sql implements renderable {
         }
         return '';
     }
+
+    /**
+     * Overides setup to ensure it will only run a single time.
+     */
+    public function setup() {
+        // Check if the setup function has been called before, we should not run it twice.
+        // If we do the sortorder of the table will be broken.
+        if (!empty($this->setup)) {
+            return;
+        }
+        parent::setup();
+    }
 }
index fea73ea..8d5d47a 100644 (file)
@@ -446,6 +446,7 @@ $string['updategrade'] = 'Update grade';
 $string['updatetable'] = 'Save and update table';
 $string['upgradenotimplemented'] = 'Upgrade not implemented in plugin ({$a->type} {$a->subtype})';
 $string['userextensiondate'] = 'Extension granted until: {$a}';
+$string['useridlistnotcached'] = 'Aborting save. Moodle could not determine which user to save the grade against.';
 $string['userswhoneedtosubmit'] = 'Users who need to submit: {$a}';
 $string['usergrade'] = 'User grade';
 $string['validmarkingworkflowstates'] = 'Valid marking workflow states';
index aad3f96..392098a 100644 (file)
@@ -140,6 +140,9 @@ class assign {
     /** @var bool whether to exclude users with inactive enrolment */
     private $showonlyactiveenrol = null;
 
+    /** @var string A key used to identify cached userlists created by this object. */
+    private $useridlistid = null;
+
     /** @var array cached list of participants for this assignment. The cache key will be group, showactive and the context id */
     private $participants = array();
 
@@ -178,6 +181,9 @@ class assign {
 
         $this->submissionplugins = $this->load_plugins('assignsubmission');
         $this->feedbackplugins = $this->load_plugins('assignfeedback');
+
+        // Extra entropy is required for uniqid() to work on cygwin.
+        $this->useridlistid = clean_param(uniqid('', true), PARAM_ALPHANUM);
     }
 
     /**
@@ -470,18 +476,18 @@ class assign {
                     $action = 'redirect';
                     $nextpageparams['action'] = 'grade';
                     $nextpageparams['rownum'] = optional_param('rownum', 0, PARAM_INT) + 1;
-                    $nextpageparams['useridlistid'] = optional_param('useridlistid', time(), PARAM_INT);
+                    $nextpageparams['useridlistid'] = optional_param('useridlistid', $this->get_useridlist_key_id(), PARAM_ALPHANUM);
                 }
             } else if (optional_param('nosaveandprevious', null, PARAM_RAW)) {
                 $action = 'redirect';
                 $nextpageparams['action'] = 'grade';
                 $nextpageparams['rownum'] = optional_param('rownum', 0, PARAM_INT) - 1;
-                $nextpageparams['useridlistid'] = optional_param('useridlistid', time(), PARAM_INT);
+                $nextpageparams['useridlistid'] = optional_param('useridlistid', $this->get_useridlist_key_id(), PARAM_ALPHANUM);
             } else if (optional_param('nosaveandnext', null, PARAM_RAW)) {
                 $action = 'redirect';
                 $nextpageparams['action'] = 'grade';
                 $nextpageparams['rownum'] = optional_param('rownum', 0, PARAM_INT) + 1;
-                $nextpageparams['useridlistid'] = optional_param('useridlistid', time(), PARAM_INT);
+                $nextpageparams['useridlistid'] = optional_param('useridlistid', $this->get_useridlist_key_id(), PARAM_ALPHANUM);
             } else if (optional_param('savegrade', null, PARAM_RAW)) {
                 // Save changes button.
                 $action = 'grade';
@@ -514,7 +520,7 @@ class assign {
         }
 
         $returnparams = array('rownum'=>optional_param('rownum', 0, PARAM_INT),
-                              'useridlistid' => optional_param('useridlistid', time(), PARAM_INT));
+                              'useridlistid' => optional_param('useridlistid', $this->get_useridlist_key_id(), PARAM_ALPHANUM));
         $this->register_return_link($action, $returnparams);
 
         // Now show the right view page.
@@ -883,10 +889,12 @@ class assign {
         // Special case for add_instance as the coursemodule has not been set yet.
         $instance = $this->get_instance();
 
+        $eventtype = 'due';
+
         if ($instance->duedate) {
             $event = new stdClass();
 
-            $params = array('modulename'=>'assign', 'instance'=>$instance->id);
+            $params = array('modulename' => 'assign', 'instance' => $instance->id, 'eventtype' => $eventtype);
             $event->id = $DB->get_field('event', 'id', $params);
             $event->name = $instance->name;
             $event->timestart = $instance->duedate;
@@ -923,12 +931,12 @@ class assign {
                 $event->userid      = 0;
                 $event->modulename  = 'assign';
                 $event->instance    = $instance->id;
-                $event->eventtype   = 'due';
+                $event->eventtype   = $eventtype;
                 $event->timeduration = 0;
                 calendar_event::create($event);
             }
         } else {
-            $DB->delete_records('event', array('modulename'=>'assign', 'instance'=>$instance->id));
+            $DB->delete_records('event', array('modulename' => 'assign', 'instance' => $instance->id, 'eventtype' => $eventtype));
         }
     }
 
@@ -2004,39 +2012,76 @@ class assign {
         require_once($CFG->dirroot . '/mod/assign/extensionform.php');
 
         $o = '';
-        $batchusers = optional_param('selectedusers', '', PARAM_SEQUENCE);
+
         $data = new stdClass();
-        $data->extensionduedate = null;
-        $userid = 0;
-        if (!$batchusers) {
-            $userid = required_param('userid', PARAM_INT);
+        $data->id = $this->get_course_module()->id;
 
-            $flags = $this->get_user_flags($userid, false);
+        $formparams = array(
+            'instance' => $this->get_instance()
+        );
 
+        $extrauserfields = get_extra_user_fields($this->get_context());
+
+        if ($mform) {
+            $submitteddata = $mform->get_data();
+            $users = $submitteddata->selectedusers;
+            $userlist = explode(',', $users);
+
+            $data->selectedusers = $users;
+            $data->userid = 0;
+
+            $usershtml = '';
+            $usercount = 0;
+            foreach ($userlist as $userid) {
+                if ($usercount >= 5) {
+                    $usershtml .= get_string('moreusers', 'assign', count($userlist) - 5);
+                    break;
+                }
+                $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
+
+                $usershtml .= $this->get_renderer()->render(new assign_user_summary($user,
+                                                                    $this->get_course()->id,
+                                                                    has_capability('moodle/site:viewfullnames',
+                                                                    $this->get_course_context()),
+                                                                    $this->is_blind_marking(),
+                                                                    $this->get_uniqueid_for_user($user->id),
+                                                                    $extrauserfields,
+                                                                    !$this->is_active_user($userid)));
+                $usercount += 1;
+            }
+
+            $formparams['userscount'] = count($userlist);
+            $formparams['usershtml'] = $usershtml;
+
+        } else {
+            $userid = required_param('userid', PARAM_INT);
             $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
+            $flags = $this->get_user_flags($userid, false);
 
+            $data->userid = $user->id;
             if ($flags) {
                 $data->extensionduedate = $flags->extensionduedate;
             }
-            $data->userid = $userid;
-        } else {
-            $data->batchusers = $batchusers;
+
+            $usershtml = $this->get_renderer()->render(new assign_user_summary($user,
+                                                                $this->get_course()->id,
+                                                                has_capability('moodle/site:viewfullnames',
+                                                                $this->get_course_context()),
+                                                                $this->is_blind_marking(),
+                                                                $this->get_uniqueid_for_user($user->id),
+                                                                $extrauserfields,
+                                                                !$this->is_active_user($userid)));
+            $formparams['usershtml'] = $usershtml;
         }
+
+        $mform = new mod_assign_extension_form(null, $formparams);
+        $mform->set_data($data);
         $header = new assign_header($this->get_instance(),
                                     $this->get_context(),
                                     $this->show_intro(),
                                     $this->get_course_module()->id,
                                     get_string('grantextension', 'assign'));
         $o .= $this->get_renderer()->render($header);
-
-        if (!$mform) {
-            $formparams = array($this->get_course_module()->id,
-                                $userid,
-                                $batchusers,
-                                $this->get_instance(),
-                                $data);
-            $mform = new mod_assign_extension_form(null, $formparams);
-        }
         $o .= $this->get_renderer()->render(new assign_form('extensionform', $mform));
         $o .= $this->view_footer();
         return $o;
@@ -3006,16 +3051,16 @@ class assign {
 
         // If userid is passed - we are only grading a single student.
         $rownum = required_param('rownum', PARAM_INT);
-        $useridlistid = optional_param('useridlistid', time(), PARAM_INT);
+        $useridlistid = optional_param('useridlistid', $this->get_useridlist_key_id(), PARAM_ALPHANUM);
         $userid = optional_param('userid', 0, PARAM_INT);
         $attemptnumber = optional_param('attemptnumber', -1, PARAM_INT);
 
         $cache = cache::make_from_params(cache_store::MODE_SESSION, 'mod_assign', 'useridlist');
         if (!$userid) {
-            if (!$useridlist = $cache->get($this->get_course_module()->id . '_' . $useridlistid)) {
+            if (!$useridlist = $cache->get($this->get_useridlist_key($useridlistid))) {
                 $useridlist = $this->get_grading_userid_list();
             }
-            $cache->set($this->get_course_module()->id . '_' . $useridlistid, $useridlist);
+            $cache->set($this->get_useridlist_key($useridlistid), $useridlist);
         } else {
             $rownum = 0;
             $useridlist = array($userid);
@@ -3393,6 +3438,14 @@ class assign {
             $o .= $this->get_renderer()->render($gradingtable);
         }
 
+        if ($this->can_grade()) {
+            // We need to cache the order of uses in the table as the person may wish to grade them.
+            // This is done based on the row number of the user.
+            $cache = cache::make_from_params(cache_store::MODE_SESSION, 'mod_assign', 'useridlist');
+            $useridlist = $gradingtable->get_column_data('userid');
+            $cache->set($this->get_useridlist_key(), $useridlist);
+        }
+
         $currentgroup = groups_get_activity_group($this->get_course_module(), true);
         $users = array_keys($this->list_participants($currentgroup, true));
         if (count($users) != 0 && $this->can_grade()) {
@@ -3691,7 +3744,6 @@ class assign {
 
             if ($data->operation == 'grantextension') {
                 // Reset the form so the grant extension page will create the extension form.
-                $mform = null;
                 return 'grantextension';
             } else if ($data->operation == 'setmarkingworkflowstate') {
                 return 'viewbatchsetmarkingworkflowstate';
@@ -5280,34 +5332,34 @@ class assign {
         require_once($CFG->dirroot . '/mod/assign/extensionform.php');
         require_sesskey();
 
-        $batchusers = optional_param('selectedusers', '', PARAM_SEQUENCE);
-        $userid = 0;
-        if (!$batchusers) {
-            $userid = required_param('userid', PARAM_INT);
-            $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
-        }
-        $mform = new mod_assign_extension_form(null, array($this->get_course_module()->id,
-                                                           $userid,
-                                                           $batchusers,
-                                                           $this->get_instance(),
-                                                           null));
+        $formparams = array(
+            'instance' => $this->get_instance(),
+            'userscount' => 0,
+            'usershtml' => '',
+        );
+
+        $mform = new mod_assign_extension_form(null, $formparams);
 
         if ($mform->is_cancelled()) {
             return true;
         }
 
         if ($formdata = $mform->get_data()) {
-            if ($batchusers) {
-                $users = explode(',', $batchusers);
+            if (!empty($formdata->selectedusers)) {
+                $users = explode(',', $formdata->selectedusers);
                 $result = true;
                 foreach ($users as $userid) {
-                    $result = $this->save_user_extension($userid, $formdata->extensionduedate) && $result;
+                    $user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
+                    $result = $this->save_user_extension($user->id, $formdata->extensionduedate) && $result;
                 }
                 return $result;
-            } else {
-                return $this->save_user_extension($userid, $formdata->extensionduedate);
+            }
+            if (!empty($formdata->userid)) {
+                $user = $DB->get_record('user', array('id' => $formdata->userid), '*', MUST_EXIST);
+                return $this->save_user_extension($user->id, $formdata->extensionduedate);
             }
         }
+
         return false;
     }
 
@@ -6080,9 +6132,9 @@ class assign {
         $attemptnumber = $params['attemptnumber'];
         if (!$userid) {
             $cache = cache::make_from_params(cache_store::MODE_SESSION, 'mod_assign', 'useridlist');
-            if (!$useridlist = $cache->get($this->get_course_module()->id . '_' . $useridlistid)) {
+            if (!$useridlist = $cache->get($this->get_useridlist_key($useridlistid))) {
                 $useridlist = $this->get_grading_userid_list();
-                $cache->set($this->get_course_module()->id . '_' . $useridlistid, $useridlist);
+                $cache->set($this->get_useridlist_key($useridlistid), $useridlist);
             }
         } else {
             $useridlist = array($userid);
@@ -6239,7 +6291,7 @@ class assign {
         $mform->setType('rownum', PARAM_INT);
         $mform->setConstant('rownum', $rownum);
         $mform->addElement('hidden', 'useridlistid', $useridlistid);
-        $mform->setType('useridlistid', PARAM_INT);
+        $mform->setType('useridlistid', PARAM_ALPHANUM);
         $mform->addElement('hidden', 'attemptnumber', $attemptnumber);
         $mform->setType('attemptnumber', PARAM_INT);
         $mform->addElement('hidden', 'ajax', optional_param('ajax', 0, PARAM_INT));
@@ -6934,13 +6986,15 @@ class assign {
         $instance = $this->get_instance();
         $rownum = required_param('rownum', PARAM_INT);
         $attemptnumber = optional_param('attemptnumber', -1, PARAM_INT);
-        $useridlistid = optional_param('useridlistid', time(), PARAM_INT);
+        $useridlistid = optional_param('useridlistid', $this->get_useridlist_key_id(), PARAM_ALPHANUM);
         $userid = optional_param('userid', 0, PARAM_INT);
         $cache = cache::make_from_params(cache_store::MODE_SESSION, 'mod_assign', 'useridlist');
         if (!$userid) {
-            if (!$useridlist = $cache->get($this->get_course_module()->id . '_' . $useridlistid)) {
-                $useridlist = $this->get_grading_userid_list();
-                $cache->set($this->get_course_module()->id . '_' . $useridlistid, $useridlist);
+            if (!$useridlist = $cache->get($this->get_useridlist_key($useridlistid))) {
+                // If the userid list is not cached we must not save, as it is possible that the user in a
+                // given row position may not be the same now as when the grading page was generated.
+                $url = new moodle_url('/mod/assign/view.php', array('id' => $this->get_course_module()->id));
+                throw new moodle_exception('useridlistnotcached', 'mod_assign', $url);
             }
         } else {
             $useridlist = array($userid);
@@ -7428,6 +7482,28 @@ class assign {
             }
         }
     }
+
+    /**
+     * The id used to uniquily identify the cache for this instance of the assign object.
+     *
+     * @return string
+     */
+    public function get_useridlist_key_id() {
+        return $this->useridlistid;
+    }
+
+    /**
+     * Generates the key that should be used for an entry in the useridlist cache.
+     *
+     * @param string $id Generate a key for this instance (optional)
+     * @return string The key for the id, or new entry if no $id is passed.
+     */
+    public function get_useridlist_key($id = null) {
+        if ($id === null) {
+            $id = $this->get_useridlist_key_id();
+        }
+        return $this->get_course_module()->id . '_' . $id;
+    }
 }
 
 /**
index 466cda7..1e0655e 100644 (file)
@@ -1,19 +1,22 @@
 M.mod_assign = {};
 
 M.mod_assign.init_tree = function(Y, expand_all, htmlid) {
-    Y.use('yui2-treeview', function(Y) {
-        var tree = new Y.YUI2.widget.TreeView(htmlid);
+    var treeElement = Y.one('#'+htmlid);
+    if (treeElement) {
+        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;
-        });
+            tree.subscribe("clickEvent", function(node, event) {
+                // We want normal clicking which redirects to url.
+                return false;
+            });
 
-        if (expand_all) {
-            tree.expandAll();
-        }
-        tree.render();
-    });
+            if (expand_all) {
+                tree.expandAll();
+            }
+            tree.render();
+        });
+    }
 };
 
 M.mod_assign.init_grading_table = function(Y) {
index ecd4d1a..ec10f34 100644 (file)
@@ -788,7 +788,7 @@ class assign_files implements renderable {
 
         if (!empty($CFG->enableportfolios)) {
             require_once($CFG->libdir . '/portfoliolib.php');
-            if (count($files) >= 1 &&
+            if (count($files) >= 1 && !empty($sid) &&
                     has_capability('mod/assign:exportownsubmission', $this->context)) {
                 $button = new portfolio_add_button();
                 $callbackparams = array('cmid' => $this->cm->id,
@@ -823,6 +823,7 @@ class assign_files implements renderable {
         foreach ($dir['files'] as $file) {
             $file->portfoliobutton = '';
             if (!empty($CFG->enableportfolios)) {
+                require_once($CFG->libdir . '/portfoliolib.php');
                 $button = new portfolio_add_button();
                 if (has_capability('mod/assign:exportownsubmission', $this->context)) {
                     $portfolioparams = array('cmid' => $this->cm->id, 'fileid' => $file->get_id());
index 2b637f9..b090b37 100644 (file)
@@ -49,6 +49,9 @@ function xmldb_assignsubmission_comments_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
 
index 802a5e7..13eeff0 100644 (file)
@@ -47,6 +47,9 @@ function xmldb_assignsubmission_file_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
 
index 3147508..ee9c2b7 100644 (file)
@@ -49,6 +49,9 @@ function xmldb_assignsubmission_onlinetext_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
 
index fffc415..3617275 100644 (file)
@@ -13,11 +13,19 @@ Feature: Grant an extension to an offline student
       | teacher1 | Teacher | 1 | teacher1@example.com |
       | student1 | Student | 1 | student1@example.com |
       | student2 | Student | 2 | student2@example.com |
+      | student3 | Student | 3 | student3@example.com |
+      | student4 | Student | 4 | student4@example.com |
+      | student5 | Student | 5 | student5@example.com |
+      | student6 | Student | 6 | student6@example.com |
     And the following "course enrolments" exist:
       | user | course | role |
       | teacher1 | C1 | editingteacher |
       | student1 | C1 | student |
       | student2 | C1 | student |
+      | student3 | C1 | student |
+      | student4 | C1 | student |
+      | student5 | C1 | student |
+      | student6 | C1 | student |
 
   @javascript
   Scenario: Granting an extension to an offline assignment
@@ -30,6 +38,7 @@ Feature: Grant an extension to an offline student
     When I follow "View/grade all submissions"
     And I click on "Edit" "link" in the "Student 1" "table_row"
     And I follow "Grant extension"
+    And I should see "Student 1 (student1@example.com)"
     And I set the field "Enable" to "1"
     And I press "Save changes"
     Then I should see "Extension granted until:" in the "Student 1" "table_row"
@@ -51,10 +60,20 @@ Feature: Grant an extension to an offline student
     And I set the field "selectall" to "1"
     And I set the field "operation" to "Grant extension"
     And I click on "Go" "button" confirming the dialogue
+    And I should see "Student 1 (student1@example.com)"
+    And I should see "Student 2 (student2@example.com)"
+    And I should see "Student 3 (student3@example.com)"
+    And I should see "Student 4 (student4@example.com)"
+    And I should see "Student 5 (student5@example.com)"
+    And I should see "1 more..."
     And I set the field "Enable" to "1"
     And I press "Save changes"
     Then I should see "Extension granted until:" in the "Student 1" "table_row"
     And I should see "Extension granted until:" in the "Student 2" "table_row"
+    And I should see "Extension granted until:" in the "Student 3" "table_row"
+    And I should see "Extension granted until:" in the "Student 4" "table_row"
+    And I should see "Extension granted until:" in the "Student 5" "table_row"
+    And I should see "Extension granted until:" in the "Student 6" "table_row"
     And I log out
     And I log in as "student1"
     And I follow "Course 1"
index af74eeb..30a55b1 100644 (file)
@@ -2143,7 +2143,7 @@ Anchor link 2:<a title=\"bananas\" href=\"../logo-240x60.gif\">Link text</a>
         $pagination = array('userid'=>$this->students[0]->id,
                             'rownum'=>0,
                             'last'=>true,
-                            'useridlistid'=>time(),
+                            'useridlistid' => $assign->get_useridlist_key_id(),
                             'attemptnumber'=>0);
         $formparams = array($assign, $data, $pagination);
         $mform = new mod_assign_grade_form(null, $formparams);
@@ -2329,5 +2329,30 @@ Anchor link 2:<a title=\"bananas\" href=\"../logo-240x60.gif\">Link text</a>
         $this->assertTrue(in_array($this->extrastudents[0]->id, $allgroupmembers));
         $this->assertTrue(in_array($this->extrastudents[1]->id , $allgroupmembers));
     }
+
+    /**
+     * Test that the useridlist cache will retive the correct values
+     * when using assign::get_useridlist_key and assign::get_useridlist_key_id.
+     */
+    public function test_useridlist_cache() {
+        // Create an assignment object, we will use this to test the key generation functions.
+        $course = self::getDataGenerator()->create_course();
+        $assign = self::getDataGenerator()->create_module('assign', array('course' => $course->id));
+        list($courserecord, $cm) = get_course_and_cm_from_instance($assign->id, 'assign');
+        $context = context_module::instance($cm->id);
+        $assign = new assign($context, $cm, $courserecord);
+        // Create the cache.
+        $cache = cache::make_from_params(cache_store::MODE_SESSION, 'mod_assign', 'useridlist');
+        // Create an entry that we will insert into the cache.
+        $entry = array(0 => '5', 1 => '6325', 2 => '67783');
+        // Insert the value into the cache.
+        $cache->set($assign->get_useridlist_key(), $entry);
+        // Now test we can retrive the entry.
+        $this->assertEquals($entry, $cache->get($assign->get_useridlist_key()));
+        $useridlistid = clean_param($assign->get_useridlist_key_id(), PARAM_ALPHANUM);
+        $this->assertEquals($entry, $cache->get($assign->get_useridlist_key($useridlistid)));
+        // Check it will not retrive anything on an invalid key.
+        $this->assertFalse($cache->get($assign->get_useridlist_key('notvalid')));
+    }
 }
 
index 0bcae0c..01d0edd 100644 (file)
@@ -27,23 +27,22 @@ require_once($CFG->dirroot . '/mod/assign/locallib.php');
 
 $id = required_param('id', PARAM_INT);
 
-$urlparams = array('id' => $id,
-                  'action' => optional_param('action', '', PARAM_TEXT),
-                  'rownum' => optional_param('rownum', 0, PARAM_INT),
-                  'useridlistid' => optional_param('useridlistid', time(), PARAM_INT));
-
-$url = new moodle_url('/mod/assign/view.php', $urlparams);
-
 list ($course, $cm) = get_course_and_cm_from_cmid($id, 'assign');
 
 require_login($course, true, $cm);
-$PAGE->set_url($url);
 
 $context = context_module::instance($cm->id);
 
 require_capability('mod/assign:view', $context);
 
 $assign = new assign($context, $cm, $course);
+$urlparams = array('id' => $id,
+                  'action' => optional_param('action', '', PARAM_TEXT),
+                  'rownum' => optional_param('rownum', 0, PARAM_INT),
+                  'useridlistid' => optional_param('useridlistid', $assign->get_useridlist_key_id(), PARAM_ALPHANUM));
+
+$url = new moodle_url('/mod/assign/view.php', $urlparams);
+$PAGE->set_url($url);
 
 $completion=new completion_info($course);
 $completion->set_module_viewed($cm);
index 3c2f1ab..a203094 100644 (file)
@@ -128,6 +128,9 @@ function xmldb_assignment_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }
 
index 5a669a3..b430fef 100644 (file)
@@ -225,5 +225,8 @@ function xmldb_book_upgrade($oldversion) {
     // Moodle v2.9.0 release upgrade line.
     // Put any upgrade step following this.
 
+    // Moodle v3.0.0 release upgrade line.
+    // Put any upgrade step following this.
+
     return true;
 }