Merge branch 'wip_MDL-48420_m29_lasttypo' of https://github.com/skodak/moodle
authorDan Poltawski <dan@moodle.com>
Mon, 1 Dec 2014 17:08:56 +0000 (17:08 +0000)
committerDan Poltawski <dan@moodle.com>
Thu, 4 Dec 2014 11:37:52 +0000 (11:37 +0000)
174 files changed:
admin/mnet/peer_forms.php
admin/mnet/peers.php
admin/mnet/testclient.php
admin/roles/module.js
admin/settings/server.php
admin/tool/assignmentupgrade/module.js
admin/tool/log/store/legacy/classes/log/store.php
admin/tool/log/store/standard/classes/log/store.php
admin/tool/monitor/tests/eventobservers_test.php
admin/tool/spamcleaner/module.js
admin/tool/xmldb/styles_bootstrapbase.css [new file with mode: 0644]
availability/condition/completion/yui/build/moodle-availability_completion-form/moodle-availability_completion-form-debug.js
availability/condition/completion/yui/build/moodle-availability_completion-form/moodle-availability_completion-form-min.js
availability/condition/completion/yui/build/moodle-availability_completion-form/moodle-availability_completion-form.js
availability/condition/completion/yui/src/form/js/form.js
availability/condition/date/yui/build/moodle-availability_date-form/moodle-availability_date-form-debug.js
availability/condition/date/yui/build/moodle-availability_date-form/moodle-availability_date-form-min.js
availability/condition/date/yui/build/moodle-availability_date-form/moodle-availability_date-form.js
availability/condition/date/yui/src/form/js/form.js
availability/condition/grade/yui/build/moodle-availability_grade-form/moodle-availability_grade-form-debug.js
availability/condition/grade/yui/build/moodle-availability_grade-form/moodle-availability_grade-form-min.js
availability/condition/grade/yui/build/moodle-availability_grade-form/moodle-availability_grade-form.js
availability/condition/grade/yui/src/form/js/form.js
availability/condition/group/yui/build/moodle-availability_group-form/moodle-availability_group-form-debug.js
availability/condition/group/yui/build/moodle-availability_group-form/moodle-availability_group-form-min.js
availability/condition/group/yui/build/moodle-availability_group-form/moodle-availability_group-form.js
availability/condition/group/yui/src/form/js/form.js
availability/condition/grouping/yui/build/moodle-availability_grouping-form/moodle-availability_grouping-form-debug.js
availability/condition/grouping/yui/build/moodle-availability_grouping-form/moodle-availability_grouping-form-min.js
availability/condition/grouping/yui/build/moodle-availability_grouping-form/moodle-availability_grouping-form.js
availability/condition/grouping/yui/src/form/js/form.js
availability/condition/profile/yui/build/moodle-availability_profile-form/moodle-availability_profile-form-debug.js
availability/condition/profile/yui/build/moodle-availability_profile-form/moodle-availability_profile-form-min.js
availability/condition/profile/yui/build/moodle-availability_profile-form/moodle-availability_profile-form.js
availability/condition/profile/yui/src/form/js/form.js
availability/yui/build/moodle-core_availability-form/moodle-core_availability-form-debug.js
availability/yui/build/moodle-core_availability-form/moodle-core_availability-form-min.js
availability/yui/build/moodle-core_availability-form/moodle-core_availability-form.js
availability/yui/src/form/js/form.js
backup/util/helper/backup_cron_helper.class.php
backup/util/helper/backup_helper.class.php
blocks/comments/tests/behat/add_comment.feature
blocks/comments/tests/behat/behat_block_comments.php
blocks/completionstatus/block_completionstatus.php
blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-debug.js
blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-min.js
blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js
blocks/navigation/yui/src/navigation/js/navigation.js
blocks/tests/behat/configure_block_throughout_site.feature
comment/lib.php
comment/locallib.php
completion/tests/behat/behat_completion.php
completion/tests/behat/teacher_manual_completion.feature [new file with mode: 0644]
course/completion.js
course/togglecompletion.php
enrol/manual/yui/quickenrolment/quickenrolment.js
enrol/meta/addinstance_form.php
enrol/meta/lang/en/enrol_meta.php
enrol/meta/settings.php
enrol/meta/version.php
enrol/yui/otherusersmanager/otherusersmanager.js
enrol/yui/rolemanager/rolemanager.js
grade/grading/form/guide/js/guideeditor.js
grade/grading/form/rubric/js/rubriceditor.js
grade/report/grader/module.js
lang/en/access.php
lang/en/admin.php
lang/en/auth.php
lang/en/backup.php
lang/en/badges.php
lang/en/block.php
lang/en/blog.php
lang/en/bulkusers.php
lang/en/cache.php
lang/en/calendar.php
lang/en/cohort.php
lang/en/completion.php
lang/en/countries.php
lang/en/currencies.php
lang/en/dbtransfer.php
lang/en/debug.php
lang/en/editor.php
lang/en/edufields.php
lang/en/enrol.php
lang/en/error.php
lang/en/filters.php
lang/en/form.php
lang/en/grades.php
lang/en/grading.php
lang/en/group.php
lang/en/hub.php
lang/en/imscc.php
lang/en/install.php
lang/en/iso6392.php
lang/en/langconfig.php
lang/en/license.php
lang/en/mathslib.php
lang/en/message.php
lang/en/mimetypes.php
lang/en/mnet.php
lang/en/moodle.php
lang/en/my.php
lang/en/notes.php
lang/en/pagetype.php
lang/en/pix.php
lang/en/plagiarism.php
lang/en/portfolio.php
lang/en/question.php
lang/en/rating.php
lang/en/repository.php
lang/en/role.php
lang/en/search.php
lang/en/table.php
lang/en/tag.php
lang/en/timezones.php
lang/en/userkey.php
lang/en/webservice.php
lib/blocklib.php
lib/classes/task/file_temp_cleanup_task.php
lib/db/install.xml
lib/db/upgrade.php
lib/deprecatedlib.php
lib/editor/atto/upgrade.txt [new file with mode: 0644]
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/js/editor-plugin-buttons.js
lib/editor/tinymce/plugins/managefiles/module.js
lib/form/dndupload.js
lib/form/filemanager.js
lib/form/yui/build/moodle-form-showadvanced/moodle-form-showadvanced-debug.js
lib/form/yui/build/moodle-form-showadvanced/moodle-form-showadvanced-min.js
lib/form/yui/build/moodle-form-showadvanced/moodle-form-showadvanced.js
lib/form/yui/src/showadvanced/js/showadvanced.js
lib/thirdpartylibs.xml
lib/yui/build/moodle-core-dock/moodle-core-dock-debug.js
lib/yui/build/moodle-core-dock/moodle-core-dock-min.js
lib/yui/build/moodle-core-dock/moodle-core-dock.js
lib/yui/build/moodle-core-maintenancemodetimer/moodle-core-maintenancemodetimer-debug.js
lib/yui/build/moodle-core-maintenancemodetimer/moodle-core-maintenancemodetimer-min.js
lib/yui/build/moodle-core-maintenancemodetimer/moodle-core-maintenancemodetimer.js
lib/yui/src/dock/js/block.js
lib/yui/src/dock/js/dock.js
lib/yui/src/dock/js/dockeditem.js
lib/yui/src/maintenancemodetimer/js/maintenancemodetimer.js
mnet/peer.php
mnet/xmlrpc/client.php
mod/chat/gui_ajax/module.js
mod/forum/lang/en/forum.php
mod/forum/lib.php
mod/forum/subscribe.php
mod/forum/tests/behat/discussion_subscriptions.feature
mod/forum/tests/mail_test.php
mod/imscp/module.js
mod/lesson/format.php
mod/lti/mod_form.js
mod/quiz/lang/en/quiz.php
mod/quiz/module.js
mod/quiz/tests/behat/behat_mod_quiz.php
mod/quiz/yui/build/moodle-mod_quiz-dragdrop/moodle-mod_quiz-dragdrop-debug.js
mod/quiz/yui/build/moodle-mod_quiz-dragdrop/moodle-mod_quiz-dragdrop-min.js
mod/quiz/yui/build/moodle-mod_quiz-dragdrop/moodle-mod_quiz-dragdrop.js
mod/quiz/yui/src/dragdrop/js/resource.js
mod/scorm/module.js
mod/scorm/view.js
mod/survey/survey.js
question/format.php
report/completion/index.php
report/completion/lang/en/report_completion.php
report/log/classes/table_log.php
repository/filepicker.js
tag/tag.js
user/selector/module.js
version.php

index ce1c1c0..a9339b0 100644 (file)
@@ -94,6 +94,15 @@ class mnet_review_host_form extends moodleform {
         $mform->setType('wwwroot', PARAM_URL);
         $mform->addRule('wwwroot', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
 
+        $options = array(
+            mnet_peer::SSL_NONE => get_string('none'),
+            mnet_peer::SSL_HOST => get_string('verifyhostonly', 'core_mnet'),
+            mnet_peer::SSL_HOST_AND_PEER => get_string('verifyhostandpeer', 'core_mnet')
+        );
+        $mform->addElement('select', 'sslverification', get_string('sslverification', 'core_mnet'), $options);
+        $mform->setDefault('sslverification', mnet_peer::SSL_HOST_AND_PEER);
+        $mform->addHelpButton('sslverification', 'sslverification', 'core_mnet');
+
         $themes = array('' => get_string('forceno'));
         foreach (array_keys(core_component::get_plugin_list('theme')) as $themename) {
             $themes[$themename] = get_string('pluginname', 'theme_'.$themename);
index 40759db..24ef9b6 100644 (file)
@@ -172,6 +172,7 @@ if ($formdata = $reviewform->get_data()) {
     $mnet_peer->public_key          = $formdata->public_key;
     $credentials                    = $mnet_peer->check_credentials($mnet_peer->public_key);
     $mnet_peer->public_key_expires  = $credentials['validTo_time_t'];
+    $mnet_peer->sslverification     = $formdata->sslverification;
 
     if ($mnet_peer->commit()) {
         redirect(new moodle_url('/admin/mnet/peers.php', array('hostid' => $mnet_peer->id)), get_string('changessaved'));
index 89734e3..f43225c 100644 (file)
@@ -66,12 +66,19 @@ if (!empty($hostid) && array_key_exists($hostid, $hosts)) {
 
     $mnet_request->set_method('system/listServices');
     $mnet_request->send($mnet_peer);
+
     $services = $mnet_request->response;
     $yesno = array('No', 'Yes');
     $servicenames = array();
 
     echo $OUTPUT->heading(get_string('servicesavailableonhost', 'mnet', $host->wwwroot));
 
+    if (!empty($mnet_request->error)) {
+        echo $OUTPUT->heading(get_string('error'), 3);
+        echo html_writer::alist($mnet_request->error);
+        $services = array();
+    }
+
     $table = new html_table();
     $table->head = array(
         get_string('serviceid', 'mnet'),
@@ -127,6 +134,7 @@ if (!empty($hostid) && array_key_exists($hostid, $hosts)) {
     echo html_writer::table($table);
 
 
+    $mnet_request = new mnet_xmlrpc_client();
     $mnet_request->set_method('system/listMethods');
     if (isset($servicename) && array_key_exists($servicename, $serviceinfo)) {
         echo $OUTPUT->heading(get_string('methodsavailableonhostinservice', 'mnet', (object)array('host' => $host->wwwroot, 'service' => $servicename)));
@@ -139,6 +147,11 @@ if (!empty($hostid) && array_key_exists($hostid, $hosts)) {
     $mnet_request->send($mnet_peer);
     $methods = $mnet_request->response;
 
+    if (!empty($mnet_request->error)) {
+        echo $OUTPUT->heading(get_string('error'), 3);
+        echo html_writer::alist($mnet_request->error);
+        $methods = array();
+    }
 
     $table = new html_table();
     $table->head = array(
@@ -171,6 +184,12 @@ if (!empty($hostid) && array_key_exists($hostid, $hosts)) {
 
         echo $OUTPUT->heading(get_string('methodsignature', 'mnet', $method));
 
+        if (!empty($mnet_request->error)) {
+            echo $OUTPUT->heading(get_string('error'), 3);
+            echo html_writer::alist($mnet_request->error);
+            $signature = array();
+        }
+
         $table = new html_table();
         $table->head = array(
             get_string('position', 'mnet'),
index 0cac01a..9c331f1 100644 (file)
@@ -53,9 +53,9 @@ M.core_role.init_cap_table_filter = function(Y, tableid, contextid) {
             // Create the capability search input.
             this.input = Y.Node.create('<input type="text" id="'+this.table.get('id')+'capabilitysearch" value="'+Y.Escape.html(filtervalue)+'" />');
             // Create a label for the search input.
-            this.label = Y.Node.create('<label for="'+this.input.get('id')+'">'+M.str.moodle.filter+' </label>');
+            this.label = Y.Node.create('<label for="'+this.input.get('id')+'">'+M.util.get_string('filter', 'moodle')+' </label>');
             // Create a clear button to clear the input.
-            this.button = Y.Node.create('<input type="button" value="'+M.str.moodle.clear+'" />').set('disabled', filtervalue=='');
+            this.button = Y.Node.create('<input type="button" value="'+M.util.get_string('clear', 'moodle')+'" />').set('disabled', filtervalue=='');
 
             // Tie it all together
             this.div.append(this.label).append(this.input).append(this.button);
index 29a5966..4b3b11e 100644 (file)
@@ -153,6 +153,19 @@ $temp->add(new admin_setting_configselect('gradehistorylifetime', new lang_strin
                                                                                                      60 => new lang_string('numdays', '', 60),
                                                                                                      30 => new lang_string('numdays', '', 30))));
 
+$temp->add(new admin_setting_configselect('tempdatafoldercleanup', new lang_string('tempdatafoldercleanup', 'admin'),
+        new lang_string('configtempdatafoldercleanup', 'admin'), 168, array(
+            1 => new lang_string('numhours', '', 1),
+            3 => new lang_string('numhours', '', 3),
+            6 => new lang_string('numhours', '', 6),
+            9 => new lang_string('numhours', '', 9),
+            12 => new lang_string('numhours', '', 12),
+            18 => new lang_string('numhours', '', 18),
+            24 => new lang_string('numhours', '', 24),
+            48 => new lang_string('numdays', '', 2),
+            168 => new lang_string('numdays', '', 7),
+)));
+
 $ADMIN->add('server', $temp);
 
 
index 933408a..ab7f670 100644 (file)
@@ -55,7 +55,7 @@ M.tool_assignmentupgrade = {
             assignmentsinput = Y.one('input.selectedassignments');
             assignmentsinput.set('value', selectedassignments.join(','));
             if (selectedassignments.length == 0) {
-                alert(M.str.tool_assignmentupgrade.noassignmentsselected);
+                alert(M.util.get_string('noassignmentsselected', 'tool_assignmentupgrade'));
                 e.preventDefault();
             }
         });
index 48d561e..faabf71 100644 (file)
@@ -95,7 +95,7 @@ class store implements \tool_log\log\store, \core\log\sql_select_reader {
         $records = array();
 
         try {
-            $records = $DB->get_records_select('log', $selectwhere, $params, $sort, '*', $limitfrom, $limitnum);
+            $records = $DB->get_recordset_select('log', $selectwhere, $params, $sort, '*', $limitfrom, $limitnum);
         } catch (\moodle_exception $ex) {
             debugging("error converting legacy event data " . $ex->getMessage() . $ex->debuginfo, DEBUG_DEVELOPER);
         }
@@ -104,6 +104,8 @@ class store implements \tool_log\log\store, \core\log\sql_select_reader {
             $events[$data->id] = \logstore_legacy\event\legacy_logged::restore_legacy($data);
         }
 
+        $records->close();
+
         return $events;
     }
 
index 992d4cf..44c66de 100644 (file)
@@ -72,7 +72,7 @@ class store implements \tool_log\log\writer, \core\log\sql_internal_reader {
         $sort = self::tweak_sort_by_id($sort);
 
         $events = array();
-        $records = $DB->get_records_select('logstore_standard_log', $selectwhere, $params, $sort, '*', $limitfrom, $limitnum);
+        $records = $DB->get_recordset_select('logstore_standard_log', $selectwhere, $params, $sort, '*', $limitfrom, $limitnum);
 
         foreach ($records as $data) {
             $extra = array('origin' => $data->origin, 'ip' => $data->ip, 'realuserid' => $data->realuserid);
@@ -94,6 +94,8 @@ class store implements \tool_log\log\writer, \core\log\sql_internal_reader {
             }
         }
 
+        $records->close();
+
         return $events;
     }
 
index 73b684f..79356c6 100644 (file)
@@ -404,12 +404,11 @@ class tool_monitor_eventobservers_testcase extends advanced_testcase {
      * Run adhoc tasks.
      */
     protected function run_adhock_tasks() {
-        ob_start();
         while ($task = \core\task\manager::get_next_adhoc_task(time())) {
             $task->execute();
             \core\task\manager::adhoc_task_complete($task);
         }
-        ob_clean(); // Suppress mtrace debugging info.
+        $this->expectOutputRegex("/^Sending message to the user with id \d+ for the subscription with id \d+\.\.\..Sent./ms");
     }
 
     /**
index d7cd018..166d5cd 100644 (file)
@@ -6,7 +6,7 @@ M.tool_spamcleaner = {
     del_all: function() {
         var context = M.tool_spamcleaner;
 
-        var yes = confirm(M.str.tool_spamcleaner.spamdeleteallconfirm);
+        var yes = confirm(M.util.get_string('spamdeleteallconfirm', 'tool_spamcleaner'));
         if (yes) {
             var cfg = {
                 method: "POST",
@@ -15,7 +15,7 @@ M.tool_spamcleaner = {
                         try {
                             var resp = context.Y.JSON.parse(o.responseText);
                         } catch(e) {
-                            alert(M.str.tool_spamcleaner.spaminvalidresult);
+                            alert(M.util.get_string('spaminvalidresult', 'tool_spamcleaner'));
                             return;
                         }
                         if (resp == true) {
@@ -36,7 +36,7 @@ M.tool_spamcleaner = {
             return;
         }
 
-        var yes = confirm(M.str.tool_spamcleaner.spamdeleteconfirm);
+        var yes = confirm(M.util.get_string('spamdeleteconfirm', 'tool_spamcleaner'));
         if (yes) {
             context.row = obj;
             var cfg = {
@@ -46,7 +46,7 @@ M.tool_spamcleaner = {
                         try {
                             var resp = context.Y.JSON.parse(o.responseText);
                         } catch(e) {
-                            alert(M.str.tool_spamcleaner.spaminvalidresult);
+                            alert(M.util.get_string('spaminvalidresult', 'tool_spamcleaner'));
                             return;
                         }
                         if (context.row) {
@@ -57,7 +57,7 @@ M.tool_spamcleaner = {
                                 context.row.parentNode.removeChild(context.row);
                                 context.row = null;
                             } else {
-                                alert(M.str.tool_spamcleaner.spamcannotdelete);
+                                alert(M.util.get_string('spamcannotdelete', 'tool_spamcleaner'));
                             }
                         }
                     }
@@ -83,7 +83,7 @@ M.tool_spamcleaner = {
                     try {
                         var resp = context.Y.JSON.parse(o.responseText);
                     } catch(e) {
-                        alert(M.str.tool_spamcleaner.spaminvalidresult);
+                        alert(M.util.get_string('spaminvalidresult', 'tool_spamcleaner'));
                         return;
                     }
                     if (context.row) {
diff --git a/admin/tool/xmldb/styles_bootstrapbase.css b/admin/tool/xmldb/styles_bootstrapbase.css
new file mode 100644 (file)
index 0000000..ae530cb
--- /dev/null
@@ -0,0 +1,3 @@
+.path-admin-tool-xmldb a[name="lastused"] {
+    padding-top: 50px;
+}
index 27350c4..803f565 100644 (file)
Binary files a/availability/condition/completion/yui/build/moodle-availability_completion-form/moodle-availability_completion-form-debug.js and b/availability/condition/completion/yui/build/moodle-availability_completion-form/moodle-availability_completion-form-debug.js differ
index eb98c96..17f1813 100644 (file)
Binary files a/availability/condition/completion/yui/build/moodle-availability_completion-form/moodle-availability_completion-form-min.js and b/availability/condition/completion/yui/build/moodle-availability_completion-form/moodle-availability_completion-form-min.js differ
index 27350c4..803f565 100644 (file)
Binary files a/availability/condition/completion/yui/build/moodle-availability_completion-form/moodle-availability_completion-form.js and b/availability/condition/completion/yui/build/moodle-availability_completion-form/moodle-availability_completion-form.js differ
index 926a9e4..1416260 100644 (file)
@@ -23,22 +23,21 @@ M.availability_completion.form.initInner = function(cms) {
 
 M.availability_completion.form.getNode = function(json) {
     // Create HTML structure.
-    var strings = M.str.availability_completion;
-    var html = strings.title + ' <span class="availability-group"><label>' +
-            '<span class="accesshide">' + strings.label_cm + ' </span>' +
-            '<select name="cm" title="' + strings.label_cm + '">' +
-            '<option value="0">' + M.str.moodle.choosedots + '</option>';
+    var html = M.util.get_string('title', 'availability_completion') + ' <span class="availability-group"><label>' +
+            '<span class="accesshide">' + M.util.get_string('label_cm', 'availability_completion') + ' </span>' +
+            '<select name="cm" title="' + M.util.get_string('label_cm', 'availability_completion') + '">' +
+            '<option value="0">' + M.util.get_string('choosedots', 'moodle') + '</option>';
     for (var i = 0; i < this.cms.length; i++) {
         var cm = this.cms[i];
         // String has already been escaped using format_string.
         html += '<option value="' + cm.id + '">' + cm.name + '</option>';
     }
-    html += '</select></label> <label><span class="accesshide">' + strings.label_completion +
-            ' </span><select name="e" title="' + strings.label_completion + '">' +
-            '<option value="1">' + strings.option_complete + '</option>' +
-            '<option value="0">' + strings.option_incomplete + '</option>' +
-            '<option value="2">' + strings.option_pass + '</option>' +
-            '<option value="3">' + strings.option_fail + '</option>' +
+    html += '</select></label> <label><span class="accesshide">' + M.util.get_string('label_completion', 'availability_completion') +
+            ' </span><select name="e" title="' + M.util.get_string('label_completion', 'availability_completion') + '">' +
+            '<option value="1">' + M.util.get_string('option_complete', 'availability_completion') + '</option>' +
+            '<option value="0">' + M.util.get_string('option_incomplete', 'availability_completion') + '</option>' +
+            '<option value="2">' + M.util.get_string('option_pass', 'availability_completion') + '</option>' +
+            '<option value="3">' + M.util.get_string('option_fail', 'availability_completion') + '</option>' +
             '</select></label></span>';
     var node = Y.Node.create('<span>' + html + '</span>');
 
index d84da8c..684d208 100644 (file)
Binary files a/availability/condition/date/yui/build/moodle-availability_date-form/moodle-availability_date-form-debug.js and b/availability/condition/date/yui/build/moodle-availability_date-form/moodle-availability_date-form-debug.js differ
index 7447c99..eeb12a3 100644 (file)
Binary files a/availability/condition/date/yui/build/moodle-availability_date-form/moodle-availability_date-form-min.js and b/availability/condition/date/yui/build/moodle-availability_date-form/moodle-availability_date-form-min.js differ
index d84da8c..684d208 100644 (file)
Binary files a/availability/condition/date/yui/build/moodle-availability_date-form/moodle-availability_date-form.js and b/availability/condition/date/yui/build/moodle-availability_date-form/moodle-availability_date-form.js differ
index 580c6eb..ca45ffc 100644 (file)
@@ -27,12 +27,11 @@ M.availability_date.form.initInner = function(html, defaultTime) {
 };
 
 M.availability_date.form.getNode = function(json) {
-    var strings = M.str.availability_date;
-    var html = strings.direction_before + ' <span class="availability-group">' +
-            '<label><span class="accesshide">' + strings.direction_label + ' </span>' +
+    var html = M.util.get_string('direction_before', 'availability_date') + ' <span class="availability-group">' +
+            '<label><span class="accesshide">' + M.util.get_string('direction_label', 'availability_date') + ' </span>' +
             '<select name="direction">' +
-            '<option value="&gt;=">' + strings.direction_from + '</option>' +
-            '<option value="&lt;">' + strings.direction_until + '</option>' +
+            '<option value="&gt;=">' + M.util.get_string('direction_from', 'availability_date') + '</option>' +
+            '<option value="&lt;">' + M.util.get_string('direction_until', 'availability_date') + '</option>' +
             '</select></label></span> ' + this.html;
     var node = Y.Node.create('<span>' + html + '</span>');
 
@@ -56,7 +55,7 @@ M.availability_date.form.getNode = function(json) {
                 }
             },
             failure : function() {
-                window.alert(M.str.availability_date.ajaxerror);
+                window.alert(M.util.get_string('ajaxerror', 'availability_date'));
             }
         }});
     } else {
@@ -130,7 +129,7 @@ M.availability_date.form.updateTime = function(node) {
             M.core_availability.form.update();
         },
         failure : function() {
-            window.alert(M.str.availability_date.ajaxerror);
+            window.alert(M.util.get_string('ajaxerror', 'availability_date'));
         }
     }});
 };
index 28f5f81..ad24176 100644 (file)
Binary files a/availability/condition/grade/yui/build/moodle-availability_grade-form/moodle-availability_grade-form-debug.js and b/availability/condition/grade/yui/build/moodle-availability_grade-form/moodle-availability_grade-form-debug.js differ
index 83c5e5a..57654e4 100644 (file)
Binary files a/availability/condition/grade/yui/build/moodle-availability_grade-form/moodle-availability_grade-form-min.js and b/availability/condition/grade/yui/build/moodle-availability_grade-form/moodle-availability_grade-form-min.js differ
index 28f5f81..ad24176 100644 (file)
Binary files a/availability/condition/grade/yui/build/moodle-availability_grade-form/moodle-availability_grade-form.js and b/availability/condition/grade/yui/build/moodle-availability_grade-form/moodle-availability_grade-form.js differ
index e0b0fe9..92108aa 100644 (file)
@@ -35,24 +35,23 @@ M.availability_grade.form.getNode = function(json) {
     this.nodesSoFar++;
 
     // Create HTML structure.
-    var strings = M.str.availability_grade;
-    var html = '<label>' + strings.title + ' <span class="availability-group">' +
-            '<select name="id"><option value="0">' + M.str.moodle.choosedots + '</option>';
+    var html = '<label>' + M.util.get_string('title', 'availability_grade') + ' <span class="availability-group">' +
+            '<select name="id"><option value="0">' + M.util.get_string('choosedots', 'moodle') + '</option>';
     for (var i = 0; i < this.grades.length; i++) {
         var grade = this.grades[i];
         // String has already been escaped using format_string.
         html += '<option value="' + grade.id + '">' + grade.name + '</option>';
     }
     html += '</select></span></label> <span class="availability-group">' +
-            '<label><input type="checkbox" name="min"/>' + strings.option_min +
-            '</label> <label><span class="accesshide">' + strings.label_min +
+            '<label><input type="checkbox" name="min"/>' + M.util.get_string('option_min', 'availability_grade') +
+            '</label> <label><span class="accesshide">' + M.util.get_string('label_min', 'availability_grade') +
             '</span><input type="text" name="minval" title="' +
-            strings.label_min + '"/></label>%</span>' +
+            M.util.get_string('label_min', 'availability_grade') + '"/></label>%</span>' +
             '<span class="availability-group">' +
-            '<label><input type="checkbox" name="max"/>' + strings.option_max +
-            '</label> <label><span class="accesshide">' + strings.label_max +
+            '<label><input type="checkbox" name="max"/>' + M.util.get_string('option_max', 'availability_grade') +
+            '</label> <label><span class="accesshide">' + M.util.get_string('label_max', 'availability_grade') +
             '</span><input type="text" name="maxval" title="' +
-            strings.label_max + '"/></label>%</span>';
+            M.util.get_string('label_max', 'availability_grade') + '"/></label>%</span>';
     var node = Y.Node.create('<span>' + html + '</span>');
 
     // Set initial values.
index a968d4e..a1b8a65 100644 (file)
Binary files a/availability/condition/group/yui/build/moodle-availability_group-form/moodle-availability_group-form-debug.js and b/availability/condition/group/yui/build/moodle-availability_group-form/moodle-availability_group-form-debug.js differ
index a5fe42f..3949118 100644 (file)
Binary files a/availability/condition/group/yui/build/moodle-availability_group-form/moodle-availability_group-form-min.js and b/availability/condition/group/yui/build/moodle-availability_group-form/moodle-availability_group-form-min.js differ
index a968d4e..a1b8a65 100644 (file)
Binary files a/availability/condition/group/yui/build/moodle-availability_group-form/moodle-availability_group-form.js and b/availability/condition/group/yui/build/moodle-availability_group-form/moodle-availability_group-form.js differ
index e68a703..f9ec44f 100644 (file)
@@ -31,11 +31,10 @@ M.availability_group.form.initInner = function(groups) {
 
 M.availability_group.form.getNode = function(json) {
     // Create HTML structure.
-    var strings = M.str.availability_group;
-    var html = '<label>' + strings.title + ' <span class="availability-group">' +
+    var html = '<label>' + M.util.get_string('title', 'availability_group') + ' <span class="availability-group">' +
             '<select name="id">' +
-            '<option value="choose">' + M.str.moodle.choosedots + '</option>' +
-            '<option value="any">' + strings.anygroup + '</option>';
+            '<option value="choose">' + M.util.get_string('choosedots', 'moodle') + '</option>' +
+            '<option value="any">' + M.util.get_string('anygroup', 'availability_group') + '</option>';
     for (var i = 0; i < this.groups.length; i++) {
         var group = this.groups[i];
         // String has already been escaped using format_string.
index 4c0a4ab..f3d616a 100644 (file)
Binary files a/availability/condition/grouping/yui/build/moodle-availability_grouping-form/moodle-availability_grouping-form-debug.js and b/availability/condition/grouping/yui/build/moodle-availability_grouping-form/moodle-availability_grouping-form-debug.js differ
index 305d8d5..34c9759 100644 (file)
Binary files a/availability/condition/grouping/yui/build/moodle-availability_grouping-form/moodle-availability_grouping-form-min.js and b/availability/condition/grouping/yui/build/moodle-availability_grouping-form/moodle-availability_grouping-form-min.js differ
index 4c0a4ab..f3d616a 100644 (file)
Binary files a/availability/condition/grouping/yui/build/moodle-availability_grouping-form/moodle-availability_grouping-form.js and b/availability/condition/grouping/yui/build/moodle-availability_grouping-form/moodle-availability_grouping-form.js differ
index dc09e83..b0fd7c9 100644 (file)
@@ -31,10 +31,9 @@ M.availability_grouping.form.initInner = function(groupings) {
 
 M.availability_grouping.form.getNode = function(json) {
     // Create HTML structure.
-    var strings = M.str.availability_grouping;
-    var html = '<label>' + strings.title + ' <span class="availability-group">' +
+    var html = '<label>' + M.util.get_string('title', 'availability_grouping') + ' <span class="availability-group">' +
             '<select name="id">' +
-            '<option value="choose">' + M.str.moodle.choosedots + '</option>';
+            '<option value="choose">' + M.util.get_string('choosedots', 'moodle') + '</option>';
     for (var i = 0; i < this.groupings.length; i++) {
         var grouping = this.groupings[i];
         // String has already been escaped using format_string.
index c4b906d..be46a7e 100644 (file)
Binary files a/availability/condition/profile/yui/build/moodle-availability_profile-form/moodle-availability_profile-form-debug.js and b/availability/condition/profile/yui/build/moodle-availability_profile-form/moodle-availability_profile-form-debug.js differ
index 6251004..63a87d3 100644 (file)
Binary files a/availability/condition/profile/yui/build/moodle-availability_profile-form/moodle-availability_profile-form-min.js and b/availability/condition/profile/yui/build/moodle-availability_profile-form/moodle-availability_profile-form-min.js differ
index c4b906d..be46a7e 100644 (file)
Binary files a/availability/condition/profile/yui/build/moodle-availability_profile-form/moodle-availability_profile-form.js and b/availability/condition/profile/yui/build/moodle-availability_profile-form/moodle-availability_profile-form.js differ
index aa01d6a..5336589 100644 (file)
@@ -33,10 +33,9 @@ M.availability_profile.form.initInner = function(standardFields, customFields) {
 
 M.availability_profile.form.getNode = function(json) {
     // Create HTML structure.
-    var strings = M.str.availability_profile;
-    var html = '<span class="availability-group"><label>' + strings.conditiontitle + ' ' +
+    var html = '<span class="availability-group"><label>' + M.util.get_string('conditiontitle', 'availability_profile') + ' ' +
             '<select name="field">' +
-            '<option value="choose">' + M.str.moodle.choosedots + '</option>';
+            '<option value="choose">' + M.util.get_string('choosedots', 'moodle') + '</option>';
     var fieldInfo;
     for (var i = 0; i < this.standardFields.length; i++) {
         fieldInfo = this.standardFields[i];
@@ -48,17 +47,17 @@ M.availability_profile.form.getNode = function(json) {
         // String has already been escaped using format_string.
         html += '<option value="cf_' + fieldInfo.field + '">' + fieldInfo.display + '</option>';
     }
-    html += '</select></label> <label><span class="accesshide">' + strings.label_operator +
-            ' </span><select name="op" title="' + strings.label_operator + '">';
+    html += '</select></label> <label><span class="accesshide">' + M.util.get_string('label_operator', 'availability_profile') +
+            ' </span><select name="op" title="' + M.util.get_string('label_operator', 'availability_profile') + '">';
     var operators = ['isequalto', 'contains', 'doesnotcontain', 'startswith', 'endswith',
             'isempty', 'isnotempty'];
     for (i = 0; i < operators.length; i++) {
         html += '<option value="' + operators[i] + '">' +
-                strings['op_' + operators[i]] + '</option>';
+                M.util.get_string('op_' + operators[i], 'availability_profile') + '</option>';
     }
-    html += '</select></label> <label><span class="accesshide">' + strings.label_value +
+    html += '</select></label> <label><span class="accesshide">' + M.util.get_string('label_value', 'availability_profile') +
             '</span><input name="value" type="text" style="width: 10em" title="' +
-            strings.label_value + '"/></label></span>';
+            M.util.get_string('label_value', 'availability_profile') + '"/></label></span>';
     var node = Y.Node.create('<span>' + html + '</span>');
 
     // Set initial values if specified.
index 185800c..1af7df2 100644 (file)
Binary files a/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form-debug.js and b/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form-debug.js differ
index 9c578a0..4733ed5 100644 (file)
Binary files a/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form-min.js and b/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form-min.js differ
index 185800c..1af7df2 100644 (file)
Binary files a/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form.js and b/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form.js differ
index 099fe5e..f0012e4 100644 (file)
@@ -258,24 +258,23 @@ M.core_availability.List = function(json, root, parentRoot) {
     if (root !== undefined) {
         this.root = root;
     }
-    var strings = M.str.availability;
     // Create DIV structure (without kids).
     this.node = Y.Node.create('<div class="availability-list"><h3 class="accesshide"></h3>' +
             '<div class="availability-inner">' +
-            '<div class="availability-header">' + strings.listheader_sign_before +
-            ' <label><span class="accesshide">' + strings.label_sign +
-            ' </span><select class="availability-neg" title="' + strings.label_sign + '">' +
-            '<option value="">' + strings.listheader_sign_pos + '</option>' +
-            '<option value="!">' + strings.listheader_sign_neg + '</option></select></label> ' +
-            '<span class="availability-single">' + strings.listheader_single + '</span>' +
-            '<span class="availability-multi">' + strings.listheader_multi_before +
-            ' <label><span class="accesshide">' + strings.label_multi + ' </span>' +
-            '<select class="availability-op" title="' + strings.label_multi + '"><option value="&">' +
-            strings.listheader_multi_and + '</option>' +
-            '<option value="|">' + strings.listheader_multi_or + '</option></select></label> ' +
-            strings.listheader_multi_after + '</span></div>' +
+            '<div class="availability-header">' + M.util.get_string('listheader_sign_before', 'availability') +
+            ' <label><span class="accesshide">' + M.util.get_string('label_sign', 'availability') +
+            ' </span><select class="availability-neg" title="' + M.util.get_string('label_sign', 'availability') + '">' +
+            '<option value="">' + M.util.get_string('listheader_sign_pos', 'availability') + '</option>' +
+            '<option value="!">' + M.util.get_string('listheader_sign_neg', 'availability') + '</option></select></label> ' +
+            '<span class="availability-single">' + M.util.get_string('listheader_single', 'availability') + '</span>' +
+            '<span class="availability-multi">' + M.util.get_string('listheader_multi_before', 'availability') +
+            ' <label><span class="accesshide">' + M.util.get_string('label_multi', 'availability') + ' </span>' +
+            '<select class="availability-op" title="' + M.util.get_string('label_multi', 'availability') + '"><option value="&">' +
+            M.util.get_string('listheader_multi_and', 'availability') + '</option>' +
+            '<option value="|">' + M.util.get_string('listheader_multi_or', 'availability') + '</option></select></label> ' +
+            M.util.get_string('listheader_multi_after', 'availability') + '</span></div>' +
             '<div class="availability-children"></div>' +
-            '<div class="availability-none">' + M.str.moodle.none + '</div>' +
+            '<div class="availability-none">' + M.util.get_string('none', 'moodle') + '</div>' +
             '<div class="availability-button"></div></div></div>');
     if (!root) {
         this.node.addClass('availability-childlist');
@@ -311,12 +310,12 @@ M.core_availability.List = function(json, root, parentRoot) {
 
         // Also if it's not the root, none is actually invalid, so add a label.
         noneNode.appendChild(Y.Node.create('<span class="label label-warning">' +
-                M.str.availability.invalid + '</span>'));
+                M.util.get_string('invalid', 'availability') + '</span>'));
     }
 
     // Create the button and add it.
     var button = Y.Node.create('<button type="button" class="btn btn-default">' +
-            M.str.availability.addrestriction + '</button>');
+            M.util.get_string('addrestriction', 'availability') + '</button>');
     button.on("click", function() { this.clickAdd(); }, this);
     this.node.one('div.availability-button').appendChild(button);
 
@@ -507,9 +506,9 @@ M.core_availability.List.prototype.updateHtml = function() {
     // Update connector text.
     var connectorText;
     if (this.inner.one('.availability-op').get('value') === '&') {
-        connectorText = M.str.availability.and;
+        connectorText = M.util.get_string('and', 'availability');
     } else {
-        connectorText = M.str.availability.or;
+        connectorText = M.util.get_string('or', 'availability');
     }
     this.inner.all('> .availability-children > .availability-connector span.label').each(function(span) {
         span.set('innerHTML', connectorText);
@@ -571,7 +570,7 @@ M.core_availability.List.prototype.clickAdd = function() {
     var content = Y.Node.create('<div>' +
             '<ul class="list-unstyled"></ul>' +
             '<div class="availability-buttons mdl-align">' +
-            '<button type="button" class="btn btn-default">' + M.str.moodle.cancel +
+            '<button type="button" class="btn btn-default">' + M.util.get_string('cancel', 'moodle') +
             '</button></div></div>');
     var cancel = content.one('button');
 
@@ -587,13 +586,12 @@ M.core_availability.List.prototype.clickAdd = function() {
         // Add entry for plugin.
         li = Y.Node.create('<li class="clearfix"></li>');
         id = 'availability_addrestriction_' + type;
-        var pluginStrings = M.str['availability_' + type];
         button = Y.Node.create('<button type="button" class="btn btn-default"' +
-                'id="' + id + '">' + pluginStrings.title + '</button>');
+                'id="' + id + '">' + M.util.get_string('title', 'availability_' + type) + '</button>');
         button.on('click', this.getAddHandler(type, dialogRef), this);
         li.appendChild(button);
         label = Y.Node.create('<label for="' + id + '">' +
-                pluginStrings.description + '</label>');
+                M.util.get_string('description', 'availability_' + type) + '</label>');
         li.appendChild(label);
         ul.appendChild(li);
     }
@@ -601,16 +599,16 @@ M.core_availability.List.prototype.clickAdd = function() {
     li = Y.Node.create('<li class="clearfix"></li>');
     id = 'availability_addrestriction_list_';
     button = Y.Node.create('<button type="button" class="btn btn-default"' +
-            'id="' + id + '">' + M.str.availability.condition_group + '</button>');
+            'id="' + id + '">' + M.util.get_string('condition_group', 'availability') + '</button>');
     button.on('click', this.getAddHandler(null, dialogRef), this);
     li.appendChild(button);
     label = Y.Node.create('<label for="' + id + '">' +
-            M.str.availability.condition_group_info + '</label>');
+            M.util.get_string('condition_group_info', 'availability') + '</label>');
     li.appendChild(label);
     ul.appendChild(li);
 
     var config = {
-        headerContent : M.str.availability.addrestriction,
+        headerContent : M.util.get_string('addrestriction', 'availability'),
         bodyContent : content,
         additionalBaseClass : 'availability-dialogue',
         draggable : true,
@@ -764,7 +762,7 @@ M.core_availability.Item = function(json, root) {
         // Handle undefined plugins.
         this.plugin = null;
         this.pluginNode = Y.Node.create('<div class="availability-warning">' +
-                M.str.availability.missingplugin + '</div>');
+                M.util.get_string('missingplugin', 'availability') + '</div>');
     } else {
         // Plugin is known.
         this.plugin = M.core_availability.form.plugins[json.type];
@@ -835,7 +833,7 @@ M.core_availability.Item.prototype.fillErrors = function(errors) {
     // If any errors were added, add the marker to this item.
     var errorLabel = this.node.one('> .label-warning');
     if (errors.length !== before && !errorLabel.get('firstChild')) {
-        errorLabel.appendChild(document.createTextNode(M.str.availability.invalid));
+        errorLabel.appendChild(document.createTextNode(M.util.get_string('invalid', 'availability')));
     } else if (errors.length === before && errorLabel.get('firstChild')) {
         errorLabel.get('firstChild').remove();
     }
@@ -851,7 +849,7 @@ M.core_availability.Item.prototype.renumber = function(number) {
     // Update heading for item.
     var headingParams = { number: number };
     if (this.plugin) {
-        headingParams.type = M.str['availability_' + this.pluginType].title;
+        headingParams.type = M.util.get_string('title', 'availability_' + this.pluginType);
     } else {
         headingParams.type = '[' + this.pluginType + ']';
     }
@@ -930,19 +928,21 @@ M.core_availability.EyeIcon = function(individual, shown) {
     this.span.appendChild(icon);
 
     // Set up button text and icon.
-    var suffix = individual ? '_individual' : '_all';
-    var setHidden = function() {
-        icon.set('src', M.util.image_url('i/show', 'core'));
-        icon.set('alt', M.str.availability['hidden' + suffix]);
-        this.span.set('title', M.str.availability['hidden' + suffix] + ' \u2022 ' +
-                M.str.availability.show_verb);
-    };
-    var setShown = function() {
-        icon.set('src', M.util.image_url('i/hide', 'core'));
-        icon.set('alt', M.str.availability['shown' + suffix]);
-        this.span.set('title', M.str.availability['shown' + suffix] + ' \u2022 ' +
-                M.str.availability.hide_verb);
-    };
+    var suffix = individual ? '_individual' : '_all',
+        setHidden = function() {
+            var hiddenStr = M.util.get_string('hidden' + suffix, 'availability');
+            icon.set('src', M.util.image_url('i/show', 'core'));
+            icon.set('alt', hiddenStr);
+            this.span.set('title', hiddenStr + ' \u2022 ' +
+                    M.util.get_string('show_verb', 'availability'));
+        },
+        setShown = function() {
+            var shownStr = M.util.get_string('shown' + suffix, 'availability');
+            icon.set('src', M.util.image_url('i/hide', 'core'));
+            icon.set('alt', shownStr);
+            this.span.set('title', shownStr + ' \u2022 ' +
+                    M.util.get_string('hide_verb', 'availability'));
+        };
     if(shown) {
         setShown.call(this);
     } else {
@@ -987,8 +987,8 @@ M.core_availability.EyeIcon.prototype.span = null;
  * @return {Boolean} True if this icon is set to 'hidden'
  */
 M.core_availability.EyeIcon.prototype.isHidden = function() {
-    var suffix = this.individual ? '_individual' : '_all';
-    var compare = M.str.availability['hidden' + suffix];
+    var suffix = this.individual ? '_individual' : '_all',
+        compare = M.util.get_string('hidden' + suffix, 'availability');
     return this.span.one('img').get('alt') === compare;
 };
 
@@ -1002,9 +1002,9 @@ M.core_availability.EyeIcon.prototype.isHidden = function() {
  */
 M.core_availability.DeleteIcon = function(toDelete) {
     this.span = Y.Node.create('<a class="availability-delete" href="#" title="' +
-            M.str.moodle['delete'] + '" role="button">');
+            M.util.get_string('delete', 'moodle') + '" role="button">');
     var img = Y.Node.create('<img src="' + M.util.image_url('t/delete', 'core') +
-            '" alt="' + M.str.moodle['delete'] + '" />');
+            '" alt="' + M.util.get_string('delete', 'moodle') + '" />');
     this.span.appendChild(img);
     var click = function(e) {
         e.preventDefault();
index 7f76cff..5adb973 100644 (file)
@@ -396,18 +396,36 @@ abstract class backup_cron_automated_helper {
             $results = $bc->get_results();
             $outcome = self::outcome_from_results($results);
             $file = $results['backup_destination']; // May be empty if file already moved to target location.
-            if (!file_exists($dir) || !is_dir($dir) || !is_writable($dir)) {
+
+            if (empty($dir) && $storage !== 0) {
+                // This is intentionally left as a warning instead of an error because of the current behaviour of backup settings.
+                // See MDL-48266 for details.
+                $bc->log('No directory specified for automated backups',
+                        backup::LOG_WARNING);
+                $outcome = self::BACKUP_STATUS_WARNING;
+            } else if (!file_exists($dir) || !is_dir($dir) || !is_writable($dir) && $storage !== 0) {
+                // If we need to copy the backup file to an external dir and it is not writable, change status to error.
+                $bc->log('Specified backup directory is not writable - ',
+                        backup::LOG_ERROR, $dir);
                 $dir = null;
+                $outcome = self::BACKUP_STATUS_ERROR;
             }
+
             // Copy file only if there was no error.
             if ($file && !empty($dir) && $storage !== 0 && $outcome != self::BACKUP_STATUS_ERROR) {
                 $filename = backup_plan_dbops::get_default_backup_filename($format, $type, $course->id, $users, $anonymised,
                         !$config->backup_shortname);
                 if (!$file->copy_content_to($dir.'/'.$filename)) {
+                    $bc->log('Attempt to copy backup file to the specified directory failed - ',
+                            backup::LOG_ERROR, $dir);
                     $outcome = self::BACKUP_STATUS_ERROR;
                 }
                 if ($outcome != self::BACKUP_STATUS_ERROR && $storage === 1) {
-                    $file->delete();
+                    if (!$file->delete()) {
+                        $outcome = self::BACKUP_STATUS_WARNING;
+                        $bc->log('Attempt to delete the backup file from course automated backup area failed - ',
+                                backup::LOG_WARNING, $file->get_filename());
+                    }
                 }
             }
 
index 963e471..4096371 100644 (file)
@@ -298,6 +298,10 @@ abstract class backup_helper {
                     @chmod($filedest, $CFG->filepermissions); // may fail because the permissions may not make sense outside of dataroot
                     unlink($filepath);
                     return null;
+                } else {
+                    $bc = backup_controller::load_controller($backupid);
+                    $bc->log('Attempt to copy backup file to the specified directory using filesystem failed - ',
+                            backup::LOG_WARNING, $dir);
                 }
                 // bad luck, try to deal with the file the old way - keep backup in file area if we can not copy to ext system
             }
index 1fd16c6..3619914 100644 (file)
@@ -33,3 +33,67 @@ Feature: Add a comment to the comments block
     When I follow "Show comments"
     And I add "I'm a comment from student1" comment to comments block
     Then I should see "I'm a comment from student1"
+
+  @javascript
+  Scenario: Test comment block pagination
+    When I add "Super test comment 01" comment to comments block
+    And I add "Super test comment 02" comment to comments block
+    And I add "Super test comment 03" comment to comments block
+    And I add "Super test comment 04" comment to comments block
+    And I add "Super test comment 05" comment to comments block
+    And I add "Super test comment 06" comment to comments block
+    And I add "Super test comment 07" comment to comments block
+    And I add "Super test comment 08" comment to comments block
+    And I add "Super test comment 09" comment to comments block
+    And I add "Super test comment 10" comment to comments block
+    And I add "Super test comment 11" comment to comments block
+    And I add "Super test comment 12" comment to comments block
+    And I add "Super test comment 13" comment to comments block
+    And I add "Super test comment 14" comment to comments block
+    And I add "Super test comment 15" comment to comments block
+    And I add "Super test comment 16" comment to comments block
+    And I add "Super test comment 17" comment to comments block
+    And I add "Super test comment 18" comment to comments block
+    And I add "Super test comment 19" comment to comments block
+    And I add "Super test comment 20" comment to comments block
+    And I add "Super test comment 21" comment to comments block
+    And I add "Super test comment 22" comment to comments block
+    And I add "Super test comment 23" comment to comments block
+    And I add "Super test comment 24" comment to comments block
+    And I add "Super test comment 25" comment to comments block
+    And I add "Super test comment 26" comment to comments block
+    And I add "Super test comment 27" comment to comments block
+    And I add "Super test comment 28" comment to comments block
+    And I add "Super test comment 29" comment to comments block
+    And I add "Super test comment 30" comment to comments block
+    And I add "Super test comment 31" comment to comments block
+    Then I should see "Super test comment 01"
+    And I should see "Super test comment 31"
+    And I follow "Course 1"
+    And I should not see "Super test comment 01"
+    And I should not see "Super test comment 02"
+    And I should not see "Super test comment 16"
+    And I should see "Super test comment 17"
+    And I should see "Super test comment 31"
+    And I should see "1" in the ".block_comments .comment-paging" "css_element"
+    And I should see "2" in the ".block_comments .comment-paging" "css_element"
+    And I should see "3" in the ".block_comments .comment-paging" "css_element"
+    And I should not see "4" in the ".block_comments .comment-paging" "css_element"
+    And I click on "2" "link" in the ".block_comments .comment-paging" "css_element"
+    And I should not see "Super test comment 01"
+    And I should see "Super test comment 02"
+    And I should see "Super test comment 16"
+    And I should not see "Super test comment 17"
+    And I should not see "Super test comment 31"
+    And I click on "3" "link" in the ".block_comments .comment-paging" "css_element"
+    And I should see "Super test comment 01"
+    And I should not see "Super test comment 02"
+    And I should not see "Super test comment 16"
+    And I should not see "Super test comment 17"
+    And I should not see "Super test comment 31"
+    And I click on "1" "link" in the ".block_comments .comment-paging" "css_element"
+    And I should not see "Super test comment 01"
+    And I should not see "Super test comment 02"
+    And I should not see "Super test comment 16"
+    And I should see "Super test comment 17"
+    And I should see "Super test comment 31"
index 094c668..491c342 100644 (file)
@@ -64,6 +64,9 @@ class behat_block_comments extends behat_base {
             $commentstextarea->setValue($comment);
 
             $this->find_link(get_string('savecomment'))->click();
+            // Delay after clicking so that additional comments will have unique time stamps.
+            // We delay 1 second which is all we need.
+            $this->getSession()->wait(1000, false);
 
         } else {
 
index c27067b..041bfe8 100644 (file)
@@ -57,6 +57,8 @@ class block_completionstatus extends block_base {
 
         // Create empty content.
         $this->content = new stdClass();
+        $this->content->text = '';
+        $this->content->footer = '';
 
         // Can edit settings?
         $can_edit = has_capability('moodle/course:update', $context);
@@ -67,13 +69,13 @@ class block_completionstatus extends block_base {
         // Don't display if completion isn't enabled!
         if (!completion_info::is_enabled_for_site()) {
             if ($can_edit) {
-                $this->content->text = get_string('completionnotenabledforsite', 'completion');
+                $this->content->text .= get_string('completionnotenabledforsite', 'completion');
             }
             return $this->content;
 
         } else if (!$info->is_enabled()) {
             if ($can_edit) {
-                $this->content->text = get_string('completionnotenabledforcourse', 'completion');
+                $this->content->text .= get_string('completionnotenabledforcourse', 'completion');
             }
             return $this->content;
         }
@@ -84,7 +86,7 @@ class block_completionstatus extends block_base {
         // Check if this course has any criteria.
         if (empty($completions)) {
             if ($can_edit) {
-                $this->content->text = get_string('nocriteriaset', 'completion');
+                $this->content->text .= get_string('nocriteriaset', 'completion');
             }
             return $this->content;
         }
@@ -230,11 +232,11 @@ class block_completionstatus extends block_base {
             $rows = array_merge($rows, $srows);
 
             $table->data = $rows;
-            $this->content->text = html_writer::table($table);
+            $this->content->text .= html_writer::table($table);
 
             // Display link to detailed view.
             $details = new moodle_url('/blocks/completionstatus/details.php', array('course' => $course->id));
-            $this->content->footer = html_writer::link($details, get_string('moredetails', 'completion'));
+            $this->content->footer .= html_writer::link($details, get_string('moredetails', 'completion'));
         } else {
             // If user is not enrolled, show error.
             $this->content->text = get_string('nottracked', 'completion');
index e02b874..b483ee2 100644 (file)
Binary files a/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-debug.js and b/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-debug.js differ
index 9431ffc..463c78c 100644 (file)
Binary files a/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-min.js and b/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation-min.js differ
index 18bccb6..37b4dd9 100644 (file)
Binary files a/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js and b/blocks/navigation/yui/build/moodle-block_navigation-navigation/moodle-block_navigation-navigation.js differ
index 52f2f08..9544816 100644 (file)
@@ -748,8 +748,8 @@ BRANCH.prototype = {
             url = M.cfg.wwwroot+'/course/index.php?categoryid=' + branch.get('key');
         }
         branch.addChild({
-            name : M.str.moodle.viewallcourses,
-            title : M.str.moodle.viewallcourses,
+            name : M.util.get_string('viewallcourses', 'moodle'),
+            title : M.util.get_string('viewallcourses', 'moodle'),
             link : url,
             haschildren : false,
             icon : {'pix':"i/navigationitem",'component':'moodle'}
index b51143a..b71303c 100644 (file)
@@ -32,3 +32,27 @@ Feature: Add and configure blocks throughout the site
     And I follow "Course 1"
     # The first block matching the pattern should be top-left block
     And I should see "Comments" in the "//*[@id='region-pre' or @id='block-region-side-pre']/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' block ')]" "xpath_element"
+
+  Scenario: Blocks on the my home page cannot have roles assigned to them
+    Given the following "users" exist:
+      | username | firstname | lastname | email |
+      | manager1 | Manager | 1 | manager1@asd.com |
+    And I log in as "manager1"
+    And I click on "My home" "link" in the "Navigation" "block"
+    When I press "Customise this page"
+    Then I should not see "Assign roles in Navigation block"
+
+  Scenario: Blocks on courses can have roles assigned to them
+    Given the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "users" exist:
+      | username | firstname | lastname | email               |
+      | teacher1 | teacher   | 1        | teacher@example.com |
+    And the following "course enrolments" exist:
+      | user     | course | role           |
+      | teacher1 | C1     | editingteacher |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I follow "Turn editing on"
+    Then I should see "Assign roles in Search forums block"
index cea8c66..17e9736 100644 (file)
@@ -48,7 +48,14 @@ class comment {
     private $courseid;
     /** @var stdClass course module object, only be used to help find pluginname automatically */
     private $cm;
-    /** @var string The component that this comment is for. It is STRONGLY recommended to set this. */
+    /**
+     * The component that this comment is for.
+     *
+     * It is STRONGLY recommended to set this.
+     * Added as a database field in 2.9, old comments will have a null component.
+     *
+     * @var string
+     */
     private $component;
     /** @var string This is calculated by normalising the component */
     private $pluginname;
@@ -241,10 +248,11 @@ class comment {
         }
         // setup variables for non-js interface
         self::$nonjs = optional_param('nonjscomment', '', PARAM_ALPHANUM);
-        self::$comment_itemid  = optional_param('comment_itemid',  '', PARAM_INT);
+        self::$comment_itemid = optional_param('comment_itemid',  '', PARAM_INT);
+        self::$comment_component = optional_param('comment_component', '', PARAM_COMPONENT);
         self::$comment_context = optional_param('comment_context', '', PARAM_INT);
-        self::$comment_page    = optional_param('comment_page',    '', PARAM_INT);
-        self::$comment_area    = optional_param('comment_area',    '', PARAM_AREA);
+        self::$comment_page = optional_param('comment_page',    '', PARAM_INT);
+        self::$comment_area = optional_param('comment_area',    '', PARAM_AREA);
 
         $page->requires->strings_for_js(array(
                 'addcomment',
@@ -264,6 +272,7 @@ class comment {
      * invalidates permission checks.
      * A coding_error is now thrown if code attempts to change the component.
      *
+     * @throws coding_exception if you try to change the component after it has been set.
      * @param string $component
      */
     public function set_component($component) {
@@ -325,6 +334,7 @@ class comment {
             'nonjscomment'    => true,
             'comment_itemid'  => $this->itemid,
             'comment_context' => $this->context->id,
+            'comment_component' => $this->get_component(),
             'comment_area'    => $this->commentarea,
         ));
         $link->remove_params(array('comment_page'));
@@ -530,10 +540,19 @@ class comment {
         $perpage = (!empty($CFG->commentsperpage))?$CFG->commentsperpage:15;
         $start = $page * $perpage;
         $ufields = user_picture::fields('u');
+
+        list($componentwhere, $component) = $this->get_component_select_sql('c');
+        if ($component) {
+            $params['component'] = $component;
+        }
+
         $sql = "SELECT $ufields, c.id AS cid, c.content AS ccontent, c.format AS cformat, c.timecreated AS ctimecreated
                   FROM {comments} c
                   JOIN {user} u ON u.id = c.userid
-                 WHERE c.contextid = :contextid AND c.commentarea = :commentarea AND c.itemid = :itemid
+                 WHERE c.contextid = :contextid AND
+                       c.commentarea = :commentarea AND
+                       c.itemid = :itemid AND
+                       $componentwhere
               ORDER BY c.timecreated DESC";
         $params['contextid'] = $this->contextid;
         $params['commentarea'] = $this->commentarea;
@@ -573,6 +592,25 @@ class comment {
         return $comments;
     }
 
+    /**
+     * Returns an SQL fragment and param for selecting on component.
+     * @param string $alias
+     * @return array
+     */
+    protected function get_component_select_sql($alias = '') {
+        $component = $this->get_component();
+        if ($alias) {
+            $alias = $alias.'.';
+        }
+        if (empty($component)) {
+            $componentwhere = "{$alias}component IS NULL";
+            $component = null;
+        } else {
+            $componentwhere = "({$alias}component IS NULL OR {$alias}component = :component)";
+        }
+        return array($componentwhere, $component);
+    }
+
     /**
      * Returns the number of comments associated with the details of this object
      *
@@ -582,7 +620,18 @@ class comment {
     public function count() {
         global $DB;
         if ($this->totalcommentcount === null) {
-            $this->totalcommentcount = $DB->count_records('comments', array('itemid' => $this->itemid, 'commentarea' => $this->commentarea, 'contextid' => $this->context->id));
+            list($where, $component) = $this->get_component_select_sql();
+            $where .= ' AND itemid = :itemid AND commentarea = :commentarea AND contextid = :contextid';
+            $params = array(
+                'itemid' => $this->itemid,
+                'commentarea' => $this->commentarea,
+                'contextid' => $this->context->id,
+            );
+            if ($component) {
+                $params['component'] = $component;
+            }
+
+            $this->totalcommentcount = $DB->count_records_select('comments', $where, $params);
         }
         return $this->totalcommentcount;
     }
@@ -641,6 +690,7 @@ class comment {
         $newcmt->contextid    = $this->contextid;
         $newcmt->commentarea  = $this->commentarea;
         $newcmt->itemid       = $this->itemid;
+        $newcmt->component    = !empty($this->component) ? $this->component : null;
         $newcmt->content      = $content;
         $newcmt->format       = $format;
         $newcmt->userid       = $USER->id;
@@ -785,10 +835,11 @@ class comment {
             return '';
         }
 
-        $html = '';
         if (!(self::$comment_itemid == $this->itemid &&
             self::$comment_context == $this->context->id &&
-            self::$comment_area == $this->commentarea)) {
+            self::$comment_area == $this->commentarea &&
+            self::$comment_component == $this->component
+        )) {
             $page = 0;
         }
         $comments = $this->get_comments($page);
@@ -918,13 +969,24 @@ class comment {
     }
 
     /**
-     * Returns the component associated with the comment
+     * Returns the component associated with the comment.
+     *
      * @return string
      */
-    public function get_compontent() {
+    public function get_component() {
         return $this->component;
     }
 
+    /**
+     * Do not call! I am a deprecated method because of the typo in my name.
+     * @deprecated since 2.9
+     * @see comment::get_component()
+     * @return string
+     */
+    public function get_compontent() {
+        return $this->get_component();
+    }
+
     /**
      * Returns the context associated with the comment
      * @return stdClass
index 606d335..14a4965 100644 (file)
@@ -62,7 +62,7 @@ class comment_manager {
         $comments = array();
 
         $usernamefields = get_all_user_name_fields(true, 'u');
-        $sql = "SELECT c.id, c.contextid, c.itemid, c.commentarea, c.userid, c.content, $usernamefields, c.timecreated
+        $sql = "SELECT c.id, c.contextid, c.itemid, c.component, c.commentarea, c.userid, c.content, $usernamefields, c.timecreated
                   FROM {comments} c
                   JOIN {user} u
                        ON u.id=c.userid
index 89b6344..807c7fe 100644 (file)
@@ -105,4 +105,20 @@ class behat_completion extends behat_base {
         return $steps;
     }
 
+    /**
+     * Toggles completion tracking for course being in the course page.
+     *
+     * @When /^completion tracking is "(?P<completion_status_string>Enabled|Disabled)" in current course$/
+     * @param string $completionstatus The status, enabled or disabled.
+     */
+    public function completion_is_toggled_in_course($completionstatus) {
+
+        $toggle = strtolower($completionstatus) == 'enabled' ? get_string('yes') : get_string('no');
+
+        return array(
+            new Given('I follow "'.get_string('editsettings').'"'),
+            new Given('I set the field "'.get_string('enablecompletion', 'completion').'" to "'.$toggle.'"'),
+            new Given('I press "'.get_string('savechanges').'"')
+        );
+    }
 }
diff --git a/completion/tests/behat/teacher_manual_completion.feature b/completion/tests/behat/teacher_manual_completion.feature
new file mode 100644 (file)
index 0000000..d15691a
--- /dev/null
@@ -0,0 +1,45 @@
+@core @core_completion
+Feature: Allow teachers to manually mark users as complete when configured
+  In order for teachers to mark students as complete
+  As a teacher
+  I need to be able to use the completion report mark complete functionality
+
+  Scenario: Mark a student as complete using the completion report
+    Given the following "courses" exist:
+      | fullname          | shortname | category |
+      | Completion course | CC1       | 0        |
+    And the following "users" exist:
+      | username | firstname | lastname | email                |
+      | student1 | Student   | First    | student1@example.com |
+      | teacher1 | Teacher   | First    | teacher1@example.com |
+    And the following "course enrolments" exist:
+      | user     | course | role           |
+      | student1 | CC1    | student        |
+      | teacher1 | CC1    | editingteacher |
+    And I log in as "admin"
+    And I set the following administration settings values:
+      | Enable completion tracking | 1 |
+    And I am on homepage
+    And I follow "Completion course"
+    And completion tracking is "Enabled" in current course
+    And I follow "Course completion"
+    And I set the field "Teacher" to "1"
+    And I press "Save changes"
+    And I turn editing mode on
+    And I add the "Course completion status" block
+    And I log out
+    And I log in as "student1"
+    And I follow "Completion course"
+    And I should see "Status: Not yet started"
+    And I log out
+    When I log in as "teacher1"
+    And I follow "Completion course"
+    And I follow "View course report"
+    And I should see "Student First"
+    And I follow "Click to mark user complete"
+    And I trigger cron
+    And I am on homepage
+    And I log out
+    Then I log in as "student1"
+    And I follow "Completion course"
+    And I should see "Status: Complete"
index 4d9542a..eb548f3 100644 (file)
@@ -18,17 +18,19 @@ M.core_completion.init = function(Y) {
 
         } else {
             var current = args.state.get('value');
-            var modulename = args.modulename.get('value');
+            var modulename = args.modulename.get('value'),
+                altstr,
+                titlestr;
             if (current == 1) {
-                var altstr = M.str.completion['completion-alt-manual-y'].replace('{$a}', modulename);
-                var titlestr = M.str.completion['completion-title-manual-y'].replace('{$a}', modulename);
+                altstr = M.util.get_string('completion-alt-manual-y', 'completion', modulename);
+                titlestr = M.util.get_string('completion-title-manual-y', 'completion', modulename);
                 args.state.set('value', 0);
                 args.image.set('src', M.util.image_url('i/completion-manual-y', 'moodle'));
                 args.image.set('alt', altstr);
                 args.image.set('title', titlestr);
             } else {
-                var altstr = M.str.completion['completion-alt-manual-n'].replace('{$a}', modulename);
-                var titlestr = M.str.completion['completion-title-manual-n'].replace('{$a}', modulename);
+                altstr = M.util.get_string('completion-alt-manual-n', 'completion', modulename);
+                titlestr = M.util.get_string('completion-title-manual-n', 'completion', modulename);
                 args.state.set('value', 1);
                 args.image.set('src', M.util.image_url('i/completion-manual-n', 'moodle'));
                 args.image.set('alt', altstr);
index 53992db..234b8c8 100644 (file)
@@ -19,6 +19,9 @@
  * Toggles the manual completion flag for a particular activity or course completion
  * and the current user.
  *
+ * If by student params: course=2
+ * If by manager params: course=2&user=4&rolec=3&sesskey=ghfgsdf
+ *
  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  * @package course
  */
@@ -31,6 +34,10 @@ $cmid = optional_param('id', 0, PARAM_INT);
 $courseid = optional_param('course', 0, PARAM_INT);
 $confirm = optional_param('confirm', 0, PARAM_BOOL);
 
+// Check if we are marking a user complete via the completion report.
+$user = optional_param('user', 0, PARAM_INT);
+$rolec = optional_param('rolec', 0, PARAM_INT);
+
 if (!$cmid && !$courseid) {
     print_error('invalidarguments');
 }
@@ -45,16 +52,14 @@ if ($courseid) {
     require_login($course);
 
     $completion = new completion_info($course);
+    $trackeduser = ($user ? $user : $USER->id);
+
     if (!$completion->is_enabled()) {
         throw new moodle_exception('completionnotenabled', 'completion');
-    } elseif (!$completion->is_tracked_user($USER->id)) {
+    } else if (!$completion->is_tracked_user($trackeduser)) {
         throw new moodle_exception('nottracked', 'completion');
     }
 
-    // Check if we are marking a user complete via the completion report
-    $user = optional_param('user', 0, PARAM_INT);
-    $rolec = optional_param('rolec', 0, PARAM_INT);
-
     if ($user && $rolec) {
         require_sesskey();
 
index 46e6e1f..f4d1bee 100644 (file)
@@ -89,7 +89,7 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
             var recovergrades = null;
             if (this.get(UEP.DISABLEGRADEHISTORY) != true) {
                 recovergrades = create('<div class="'+CSS.ENROLMENTOPTION+' '+CSS.RECOVERGRADES+'"></div>')
-                    .append(create('<label class="'+CSS.RECOVERGRADESTITLE+'" for="'+CSS.RECOVERGRADES+'">'+M.str.enrol.recovergrades+'</label>'))
+                    .append(create('<label class="'+CSS.RECOVERGRADESTITLE+'" for="'+CSS.RECOVERGRADES+'">'+M.util.get_string('recovergrades', 'enrol')+'</label>'))
                     .append(create('<input type="checkbox" id="'+CSS.RECOVERGRADES+'" name="'+CSS.RECOVERGRADES+'"'+ this.get(UEP.RECOVERGRADESDEFAULT) +' />'))
             }
 
@@ -97,21 +97,21 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
                 .append(create('<div class="'+CSS.WRAP+'"></div>')
                     .append(create('<div class="'+CSS.HEADER+' header"></div>')
                         .append(create('<div class="'+CSS.CLOSE+'"></div>'))
-                        .append(create('<h2>'+M.str.enrol.enrolusers+'</h2>')))
+                        .append(create('<h2>'+M.util.get_string('enrolusers', 'enrol')+'</h2>')))
                     .append(create('<div class="'+CSS.CONTENT+'"></div>')
                         .append(create('<div class="'+CSS.SEARCHCONTROLS+'"></div>')
-                            .append(create('<div class="'+CSS.ENROLMENTOPTION+' '+CSS.ROLE+'"><label for="id_enrol_manual_assignable_roles">'+M.str.role.assignroles+'</label></div>')
-                                    .append(create('<select id="id_enrol_manual_assignable_roles"><option value="">'+M.str.enrol.none+'</option></select>'))
+                            .append(create('<div class="'+CSS.ENROLMENTOPTION+' '+CSS.ROLE+'"><label for="id_enrol_manual_assignable_roles">'+M.util.get_string('assignroles', 'role')+'</label></div>')
+                                    .append(create('<select id="id_enrol_manual_assignable_roles"><option value="">'+M.util.get_string('none', 'enrol')+'</option></select>'))
                             )
                             .append(create('<div class="'+CSS.ENTITYSELECTOR+'"></div>'))
                             .append(create('<div class="'+CSS.SEARCHOPTIONS+'"></div>')
-                                .append(create('<div class="'+CSS.COLLAPSIBLEHEADING+'"><img alt="" />'+M.str.enrol.enrolmentoptions+'</div>'))
+                                .append(create('<div class="'+CSS.COLLAPSIBLEHEADING+'"><img alt="" />'+M.util.get_string('enrolmentoptions', 'enrol')+'</div>'))
                                 .append(create('<div class="'+CSS.COLLAPSIBLEAREA+' '+CSS.HIDDEN+'"></div>')
                                     .append(recovergrades)
-                                    .append(create('<div class="'+CSS.ENROLMENTOPTION+' '+CSS.STARTDATE+'">'+M.str.moodle.startingfrom+'</div>')
+                                    .append(create('<div class="'+CSS.ENROLMENTOPTION+' '+CSS.STARTDATE+'">'+M.util.get_string('startingfrom', 'moodle')+'</div>')
                                         .append(create('<select></select>')))
-                                    .append(create('<div class="'+CSS.ENROLMENTOPTION+' '+CSS.DURATION+'">'+M.str.enrol.enrolperiod+'</div>')
-                                        .append(create('<select><option value="0" selected="selected">'+M.str.enrol.unlimitedduration+'</option></select>')))
+                                    .append(create('<div class="'+CSS.ENROLMENTOPTION+' '+CSS.DURATION+'">'+M.util.get_string('enrolperiod', 'enrol')+'</div>')
+                                        .append(create('<select><option value="0" selected="selected">'+M.util.get_string('unlimitedduration', 'enrol')+'</option></select>')))
                                 )
                             )
                         )
@@ -121,12 +121,12 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
                                 .setAttribute('src', M.util.image_url('i/loading', 'moodle')))
                             .setStyle('opacity', 0.5)))
                     .append(create('<div class="'+CSS.FOOTER+'"></div>')
-                        .append(create('<div class="'+CSS.SEARCH+'"><label for="enrolusersearch" class="accesshide">'+M.str.enrol.usersearch+'</label></div>')
+                        .append(create('<div class="'+CSS.SEARCH+'"><label for="enrolusersearch" class="accesshide">'+M.util.get_string('usersearch', 'enrol')+'</label></div>')
                             .append(create('<input type="text" id="enrolusersearch" value="" />'))
-                                .append(create('<input type="button" id="searchbtn" class="'+CSS.SEARCHBTN+'" value="'+M.str.enrol.usersearch+'" />'))
+                                .append(create('<input type="button" id="searchbtn" class="'+CSS.SEARCHBTN+'" value="'+M.util.get_string('usersearch', 'enrol')+'" />'))
                         )
                         .append(create('<div class="'+CSS.CLOSEBTN+'"></div>')
-                            .append(create('<input type="button" value="'+M.str.enrol.finishenrollingusers+'" />'))
+                            .append(create('<input type="button" value="'+M.util.get_string('finishenrollingusers', 'enrol')+'" />'))
                         )
                     )
                 )
@@ -152,9 +152,9 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
             if (this.get(UEP.COHORTSAVAILABLE)) {
                 this.get(UEP.BASE).one('.'+CSS.ENTITYSELECTOR)
                     .append(create('<input type="radio" id="id_enrol_manual_entity_users" name="enrol_manual_entity" value="users" checked="checked"/>'))
-                    .append(create('<label for="id_enrol_manual_entity_users">'+ M.str.enrol_manual.browseusers+'</label>'))
+                    .append(create('<label for="id_enrol_manual_entity_users">'+ M.util.get_string('browseusers', 'enrol_manual')+'</label>'))
                     .append(create('<input type="radio" id="id_enrol_manual_entity_cohorts" name="enrol_manual_entity" value="cohorts"/>'))
-                    .append(create('<label for="id_enrol_manual_entity_cohorts">'+M.str.enrol_manual.browsecohorts+'</label>'));
+                    .append(create('<label for="id_enrol_manual_entity_cohorts">'+M.util.get_string('browsecohorts', 'enrol_manual')+'</label>'));
                 this.get(UEP.BASE).one('#id_enrol_manual_entity_cohorts').on('change', this.search, this);
                 this.get(UEP.BASE).one('#id_enrol_manual_entity_users').on('change', this.search, this);
             } else {
@@ -380,7 +380,7 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
                 new M.core.exception(e);
             }
             if (!result.success) {
-                this.setContent = M.str.enrol.errajaxsearch;
+                this.setContent = M.util.get_string('errajaxsearch', 'enrol');
             }
             var users;
             if (!args.append) {
@@ -401,17 +401,17 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
                         .append(create('<div class="'+CSS.FULLNAME+'">'+user.fullname+'</div>'))
                         .append(create('<div class="'+CSS.EXTRAFIELDS+'">'+user.extrafields+'</div>')))
                     .append(create('<div class="'+CSS.OPTIONS+'"></div>')
-                        .append(create('<input type="button" class="'+CSS.ENROL+'" value="'+M.str.enrol.enrol+'" />')))
+                        .append(create('<input type="button" class="'+CSS.ENROL+'" value="'+M.util.get_string('enrol', 'enrol')+'" />')))
                 );
             }
             this.set(UEP.USERCOUNT, count);
             if (!args.append) {
-                var usersstr = (result.response.totalusers == '1')?M.str.enrol.ajaxoneuserfound:M.util.get_string('ajaxxusersfound','enrol', result.response.totalusers);
+                var usersstr = (result.response.totalusers == '1')?M.util.get_string('ajaxoneuserfound', 'enrol'):M.util.get_string('ajaxxusersfound','enrol', result.response.totalusers);
                 var content = create('<div class="'+CSS.SEARCHRESULTS+'"></div>')
                     .append(create('<div class="'+CSS.TOTALUSERS+'">'+usersstr+'</div>'))
                     .append(users);
                 if (result.response.totalusers > (this.get(UEP.PAGE)+1)*this.get(UEP.PERPAGE)) {
-                    var fetchmore = create('<div class="'+CSS.MORERESULTS+'"><a href="#">'+M.str.enrol.ajaxnext25+'</a></div>');
+                    var fetchmore = create('<div class="'+CSS.MORERESULTS+'"><a href="#">'+M.util.get_string('ajaxnext25', 'enrol')+'</a></div>');
                     fetchmore.on('click', this.search, this, true);
                     content.append(fetchmore)
                 }
@@ -433,7 +433,7 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
                 new M.core.exception(e);
             }
             if (!result.success) {
-                this.setContent = M.str.enrol.errajaxsearch;
+                this.setContent = M.util.get_string('errajaxsearch', 'enrol');
             }
             var cohorts;
             if (!args.append) {
@@ -456,13 +456,13 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
             }
             this.set(UEP.COHORTCOUNT, count);
             if (!args.append) {
-                //var usersstr = (result.response.totalusers == '1')?M.str.enrol.ajaxoneuserfound:M.util.get_string('ajaxxusersfound','enrol', result.response.totalusers);
+                //var usersstr = (result.response.totalusers == '1')?M.util.get_string('ajaxoneuserfound', 'enrol'):M.util.get_string('ajaxxusersfound','enrol', result.response.totalusers);
                 var cohortsstr = 'Found '+result.response.totalcohorts+' cohorts'; // TODO
                 var content = create('<div class="'+CSS.SEARCHRESULTS+'"></div>')
                     .append(create('<div class="'+CSS.TOTALCOHORTS+'">'+cohortsstr+'</div>'))
                     .append(cohorts);
                 if (result.response.totalcohorts > (this.get(UEP.PAGE)+1)*this.get(UEP.PERPAGE)) {
-                    var fetchmore = create('<div class="'+CSS.MORERESULTS+'"><a href="#">'+M.str.enrol.ajaxnext25+'</a></div>');
+                    var fetchmore = create('<div class="'+CSS.MORERESULTS+'"><a href="#">'+M.util.get_string('ajaxnext25', 'enrol')+'</a></div>');
                     fetchmore.on('click', this.search, this, true);
                     content.append(fetchmore)
                 }
index c463082..ecc3f54 100644 (file)
@@ -42,7 +42,11 @@ class enrol_meta_addinstance_form extends moodleform {
         $courses = array('' => get_string('choosedots'));
         $select = ', ' . context_helper::get_preload_record_columns_sql('ctx');
         $join = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
-        $sql = "SELECT c.id, c.fullname, c.shortname, c.visible $select FROM {course} c $join ORDER BY c.sortorder ASC";
+
+        $plugin = enrol_get_plugin('meta');
+        $sortorder = 'c.' . $plugin->get_config('coursesort', 'sortorder') . ' ASC';
+
+        $sql = "SELECT c.id, c.fullname, c.shortname, c.visible $select FROM {course} c $join ORDER BY " . $sortorder;
         $rs = $DB->get_recordset_sql($sql, array('contextlevel' => CONTEXT_COURSE));
         foreach ($rs as $c) {
             if ($c->id == SITEID or $c->id == $course->id or isset($existing[$c->id])) {
index e554ddd..b47f526 100644 (file)
@@ -22,6 +22,8 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+$string['coursesort'] = 'Sort course list';
+$string['coursesort_help'] = 'This determines whether the list of courses that can be linked are sorted by sort order (i.e. the order set in Site administration > Courses > Manage courses and categories) or alphabetically by course setting.';
 $string['linkedcourse'] = 'Link course';
 $string['meta:config'] = 'Configure meta enrol instances';
 $string['meta:selectaslinked'] = 'Select course as meta linked';
index 3cbc4e1..8fb9a7d 100644 (file)
@@ -41,5 +41,19 @@ if ($ADMIN->fulltree) {
             ENROL_EXT_REMOVED_SUSPENDNOROLES => get_string('extremovedsuspendnoroles', 'core_enrol'),
         );
         $settings->add(new admin_setting_configselect('enrol_meta/unenrolaction', get_string('extremovedaction', 'enrol'), get_string('extremovedaction_help', 'enrol'), ENROL_EXT_REMOVED_SUSPENDNOROLES, $options));
+
+        $sortoptions = array(
+            'sortorder' => new lang_string('sort_sortorder', 'admin'),
+            'fullname' => new lang_string('sort_fullname', 'admin'),
+            'shortname' => new lang_string('sort_shortname', 'admin'),
+            'idnumber' => new lang_string('sort_idnumber', 'admin'),
+        );
+        $settings->add(new admin_setting_configselect(
+            'enrol_meta/coursesort',
+            new lang_string('coursesort', 'enrol_meta'),
+            new lang_string('coursesort_help', 'enrol_meta'),
+            'sortorder',
+            $sortoptions
+        ));
     }
 }
index df71ec9..216b532 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2014111000;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2014112400;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2014110400;        // Requires this Moodle version
 $plugin->component = 'enrol_meta';      // Full name of the plugin (used for diagnostics)
 $plugin->cron      = 60*60;             // run cron every hour by default, it is not out-of-sync often
index 1df94ce..89390ee 100644 (file)
@@ -58,7 +58,7 @@ YUI.add('moodle-enrol-otherusersmanager', function(Y) {
                 .append(Y.Node.create('<div class="'+CSS.WRAP+'"></div>')
                     .append(Y.Node.create('<div class="'+CSS.HEADER+' header"></div>')
                         .append(Y.Node.create('<div class="'+CSS.CLOSE+'"></div>'))
-                        .append(Y.Node.create('<h2>'+M.str.enrol.usersearch+'</h2>')))
+                        .append(Y.Node.create('<h2>'+M.util.get_string('usersearch', 'enrol')+'</h2>')))
                     .append(Y.Node.create('<div class="'+CSS.CONTENT+'"></div>')
                         .append(Y.Node.create('<div class="'+CSS.AJAXCONTENT+'"></div>'))
                         .append(Y.Node.create('<div class="'+CSS.LIGHTBOX+' '+CSS.HIDDEN+'"></div>')
@@ -66,7 +66,7 @@ YUI.add('moodle-enrol-otherusersmanager', function(Y) {
                                 .setAttribute('src', M.util.image_url('i/loading', 'moodle')))
                             .setStyle('opacity', 0.5)))
                     .append(Y.Node.create('<div class="'+CSS.FOOTER+'"></div>')
-                        .append(Y.Node.create('<div class="'+CSS.SEARCH+'"><label>'+M.str.enrol.usersearch+'</label></div>')
+                        .append(Y.Node.create('<div class="'+CSS.SEARCH+'"><label>'+M.util.get_string('usersearch', 'enrol')+'</label></div>')
                             .append(Y.Node.create('<input type="text" id="oump-usersearch" value="" />'))
                         )
                     )
@@ -169,7 +169,7 @@ YUI.add('moodle-enrol-otherusersmanager', function(Y) {
                 new M.core.exception(e);
             }
             if (!result.success) {
-                this.setContent = M.str.enrol.errajaxsearch;
+                this.setContent = M.util.get_string('errajaxsearch', 'enrol');
             }
             var usersnode, users = [], i=0, count=0, user;
             if (!args.append) {
@@ -186,12 +186,12 @@ YUI.add('moodle-enrol-otherusersmanager', function(Y) {
             }
             this.set(USERCOUNT, count);
             if (!args.append) {
-                var usersstr = (result.response.totalusers == '1')?M.str.enrol.ajaxoneuserfound:M.util.get_string('ajaxxusersfound','enrol', result.response.totalusers);
+                var usersstr = (result.response.totalusers == '1')?M.util.get_string('ajaxoneuserfound', 'enrol'):M.util.get_string('ajaxxusersfound','enrol', result.response.totalusers);
                 var content = Y.Node.create('<div class="'+CSS.SEARCHRESULTS+'"></div>')
                     .append(Y.Node.create('<div class="'+CSS.TOTALUSERS+'">'+usersstr+'</div>'))
                     .append(usersnode);
                 if (result.response.totalusers > (this.get(PAGE)+1)*25) {
-                    var fetchmore = Y.Node.create('<div class="'+CSS.MORERESULTS+'"><a href="#">'+M.str.enrol.ajaxnext25+'</a></div>');
+                    var fetchmore = Y.Node.create('<div class="'+CSS.MORERESULTS+'"><a href="#">'+M.util.get_string('ajaxnext25', 'enrol')+'</a></div>');
                     fetchmore.on('click', this.getUsers, this, true);
                     content.append(fetchmore)
                 }
@@ -312,7 +312,7 @@ YUI.add('moodle-enrol-otherusersmanager', function(Y) {
                         .append(Y.Node.create('<div class="'+CSS.FULLNAME+'">'+this.get(FULLNAME)+'</div>'))
                         .append(Y.Node.create('<div class="'+CSS.EXTRAFIELDS+'">'+this.get(EXTRAFIELDS)+'</div>'))
                     )
-                    .append(Y.Node.create('<div class="'+CSS.OPTIONS+'"><span class="label">'+M.str.role.assignrole+': </span></div>'))
+                    .append(Y.Node.create('<div class="'+CSS.OPTIONS+'"><span class="label">'+M.util.get_string('assignrole', 'role')+': </span></div>'))
                 );
             var id = 0, roles = this._manager.get(ASSIGNABLEROLES);
             for (id in roles) {
index 7e35cbd..6e6dfa2 100644 (file)
@@ -112,14 +112,14 @@ YUI.add('moodle-enrol-rolemanager', function(Y) {
             e.halt();
             var event = this.on('assignablerolesloaded', function(){
                 event.detach();
-                var s = M.str.role, confirmation = {
+                var confirmation = {
                     modal:  true,
                     visible  :  true,
                     centered :  true,
-                    title    :  s.confirmunassigntitle,
-                    question :  s.confirmunassign,
-                    yesLabel :  s.confirmunassignyes,
-                    noLabel  :  s.confirmunassignno
+                    title    :  M.util.get_string('confirmunassigntitle', 'role'),
+                    question :  M.util.get_string('confirmunassign', 'role'),
+                    yesLabel :  M.util.get_string('confirmunassignyes', 'role'),
+                    noLabel  :  M.util.get_string('confirmunassignno', 'role')
                 };
                 new M.core.confirm(confirmation).on('complete-yes', this.removeRoleCallback, this, user.get(USERID), roleid);
             }, this);
@@ -347,7 +347,7 @@ YUI.add('moodle-enrol-rolemanager', function(Y) {
         submitevent : null,
         initializer : function() {
             var i, m = this.get(MANIPULATOR);
-            var element = Y.Node.create('<div class="enrolpanel roleassign"><div class="container"><div class="header"><h2>'+M.str.role.assignroles+'</h2><div class="close"></div></div><div class="content"></div></div></div>');
+            var element = Y.Node.create('<div class="enrolpanel roleassign"><div class="container"><div class="header"><h2>'+M.util.get_string('assignroles', 'role')+'</h2><div class="close"></div></div><div class="content"></div></div></div>');
             var content = element.one('.content');
             var roles = m.get(ASSIGNABLEROLES);
             for (i in roles) {
index 94c1e15..bd7229d 100644 (file)
@@ -105,10 +105,10 @@ M.gradingform_guideeditor.editmode = function(el, editmode) {
         if (value.length) {
             taplain.removeClass('empty')
         } else if (ta.get('name').indexOf('[shortname]') > 1){
-            value = M.str.gradingform_guide.clicktoeditname
+            value = M.util.get_string('clicktoeditname', 'gradingform_guide')
             taplain.addClass('editname')
         } else {
-            value = M.str.gradingform_guide.clicktoedit
+            value = M.util.get_string('clicktoedit', 'gradingform_guide')
             taplain.addClass('empty')
         }
         taplain.one('.textvalue').set('innerHTML', Y.Escape.html(value))
@@ -219,7 +219,7 @@ M.gradingform_guideeditor.buttonclick = function(e, confirmed) {
             Y.one('#'+name+'-'+section+'-'+chunks[2]).remove()
             M.gradingform_guideeditor.assignclasses(elements_str)
         } else {
-            dialog_options['message'] = M.str.gradingform_guide.confirmdeletecriterion
+            dialog_options['message'] = M.util.get_string('confirmdeletecriterion', 'gradingform_guide')
             M.util.show_confirm_dialog(e, dialog_options);
         }
     } else {
index f0dd3ae..6b9137a 100644 (file)
@@ -90,7 +90,7 @@ M.gradingform_rubriceditor.editmode = function(el, editmode, focustb) {
         var value = ta.get('value')
         if (value.length) taplain.removeClass('empty')
         else {
-            value = (el.hasClass('level')) ? M.str.gradingform_rubric.levelempty : M.str.gradingform_rubric.criterionempty
+            value = (el.hasClass('level')) ? M.util.get_string('levelempty', 'gradingform_rubric') : M.util.get_string('criterionempty', 'gradingform_rubric')
             taplain.addClass('empty')
         }
         taplain.one('.textvalue').set('innerHTML', Y.Escape.html(value));
@@ -201,7 +201,7 @@ M.gradingform_rubriceditor.buttonclick = function(e, confirmed) {
             Y.one('#'+name+'-criteria-'+chunks[2]).remove()
             M.gradingform_rubriceditor.assignclasses(elements_str)
         } else {
-            dialog_options['message'] = M.str.gradingform_rubric.confirmdeletecriterion
+            dialog_options['message'] = M.util.get_string('confirmdeletecriterion', 'gradingform_rubric')
             M.util.show_confirm_dialog(e, dialog_options);
         }
     } else if (chunks.length == 6 && action == 'delete') {
@@ -210,7 +210,7 @@ M.gradingform_rubriceditor.buttonclick = function(e, confirmed) {
             Y.one('#'+name+'-criteria-'+chunks[2]+'-'+chunks[3]+'-'+chunks[4]).remove()
             M.gradingform_rubriceditor.assignclasses(elements_str)
         } else {
-            dialog_options['message'] = M.str.gradingform_rubric.confirmdeletelevel
+            dialog_options['message'] = M.util.get_string('confirmdeletelevel', 'gradingform_rubric')
             M.util.show_confirm_dialog(e, dialog_options);
         }
     } else {
index 7fa1600..706571e 100644 (file)
@@ -446,7 +446,7 @@ M.gradereport_grader.classes.ajax.prototype.submission_outcome = function(tid, o
     try {
         outcome = this.report.Y.JSON.parse(outcome.responseText);
     } catch(e) {
-        var message = M.str.gradereport_grader.ajaxfailedupdate;
+        var message = M.util.get_string('ajaxfailedupdate', 'gradereport_grader');
         message = message.replace(/\[1\]/, args.type);
         message = message.replace(/\[2\]/, this.report.users[args.properties.userid]);
 
@@ -506,7 +506,7 @@ M.gradereport_grader.classes.ajax.prototype.submission_outcome = function(tid, o
                         // If we are here the grade value of the cell currently being edited has changed !!!!!!!!!
                         // If the user has not actually changed the old value yet we will automatically correct it
                         // otherwise we will prompt the user to choose to use their value or the new value!
-                        if (!this.current.has_changed() || confirm(M.str.gradereport_grader.ajaxfieldchanged)) {
+                        if (!this.current.has_changed() || confirm(M.util.get_string('ajaxfieldchanged', 'gradereport_grader'))) {
                             this.current.set_grade(finalgrade);
                             this.current.grade.set('value', finalgrade);
                         }
@@ -554,7 +554,7 @@ M.gradereport_grader.classes.ajax.prototype.submission_outcome = function(tid, o
  */
 M.gradereport_grader.classes.ajax.prototype.display_submission_error = function(message, cell) {
     var erroroverlay = new this.report.Y.Overlay({
-        headerContent : '<div><strong class="error">'+M.str.gradereport_grader.ajaxerror+'</strong>  <em>'+M.str.gradereport_grader.ajaxclicktoclose+'</em></div>',
+        headerContent : '<div><strong class="error">'+M.util.get_string('ajaxerror', 'gradereport_grader')+'</strong>  <em>'+M.util.get_string('ajaxclicktoclose', 'gradereport_grader')+'</em></div>',
         bodyContent : message,
         visible : false,
         zIndex : 3
@@ -1009,7 +1009,7 @@ M.gradereport_grader.classes.scalefield = function(report, node) {
     this.gradespan = node.one('.gradevalue');
     this.inputdiv = this.report.Y.Node.create('<div></div>');
     this.editfeedback = this.report.ajax.showquickfeedback;
-    this.grade = this.report.Y.Node.create('<select type="text" class="text" /><option value="-1">'+M.str.gradereport_grader.ajaxchoosescale+'</option></select>');
+    this.grade = this.report.Y.Node.create('<select type="text" class="text" /><option value="-1">'+M.util.get_string('ajaxchoosescale', 'gradereport_grader')+'</option></select>');
     this.gradetype = 'scale';
     this.inputdiv.append(this.grade);
     if (this.editfeedback) {
index ee81afc..6e8789e 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'access', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   access
+ * @package   core_access
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 63e1d81..888b20d 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'admin', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   admin
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -342,6 +341,7 @@ $string['configstripalltitletags'] = 'Uncheck this setting to allow HTML tags in
 $string['configsupportemail'] = 'This email address will be published to users of this site as the one to email when they need general help (for example, when new users create their own accounts).  If this email is left blank then no such helpful email address is supplied.';
 $string['configsupportname'] = 'This is the name of a person or other entity offering general help via the support email or web address.';
 $string['configsupportpage'] = 'This web address will be published to users of this site as the one to go to when they need general help (for example, when new users create their own accounts).  If this address is left blank then no link will be supplied.';
+$string['configtempdatafoldercleanup'] = 'Remove temporary data files from the data folder that are older than the selected time.';
 $string['configthemedesignermode'] = 'Normally all theme images and style sheets are cached in browsers and on the server for a very long time, for performance. If you are designing themes or developing code then you probably want to turn this mode on so that you are not served cached versions.  Warning: this will make your site slower for all users!  Alternatively, you can also reset the theme caches manually from the Theme selection page.';
 $string['configthemelist'] = 'Leave this blank to allow any valid theme to be used.  If you want to shorten the theme menu, you can specify a comma-separated list of names here (Don\'t use spaces!).
 For example:  standard,orangewhite.';
@@ -1037,6 +1037,7 @@ $string['tasksessioncleanup'] = 'Cleanup old sessions';
 $string['taskstatscron'] = 'Background processing for statistics';
 $string['tasktagcron'] = 'Background processing for tags';
 $string['tasktempfilecleanup'] = 'Delete stale temp files';
+$string['tempdatafoldercleanup'] = 'Clean up temporary data files older than';
 $string['themedesignermode'] = 'Theme designer mode';
 $string['themelist'] = 'Theme list';
 $string['themenoselected'] = 'No theme selected';
index 0bfe51b..4e01c2c 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'auth', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   auth
+ * @package   core_auth
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index e1de7b8..6e68819 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * This file contains the strings used by backup
  *
- * @package   moodlecore
+ * @package   core
  * @copyright 2010 Eloy
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index ddb6691..21cf94e 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Language file for 'badges' component
  *
- * @package    core
+ * @package    core_badges
  * @subpackage badges
  * @copyright  2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
index e38b5a4..7b31859 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'block', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   block
+ * @package   core_block
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 0904968..10193b2 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,8 +17,7 @@
 /**
  * Strings for core subsystem 'blog'
  *
- * @package    core
- * @subpackage blog
+ * @package    core_blog
  * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 28571d2..deb03d1 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
index 6feeadf..db531a5 100644 (file)
@@ -20,7 +20,7 @@
  * This file is part of Moodle's cache API, affectionately called MUC.
  * It contains the components that are requried in order to use caching.
  *
- * @package    core
+ * @package    core_cache
  * @category   cache
  * @copyright  2012 Sam Hemelryk
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
index 475e340..7215442 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'calendar', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   calendar
+ * @package   core_calendar
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 868194e..7b1dc38 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'cohort', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package    moodlecore
+ * @package    core_cohort
  * @subpackage cohort
  * @copyright  2010 Petr Skoda (info@skodak.org)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
index 2573482..4dca573 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
index bab797f..dc2046e 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'countries', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   countries
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index eb032e8..c5c3459 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'currencies', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   currencies
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 0bd37d5..eae0e68 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,8 @@
 /**
  * Strings for component 'dbtransfer', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   dbtransfer
+ * @package   core
+ * @subpackage dbtransfer
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index a18c1bc..bfd0c89 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'debug', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   debug
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index d2922d6..123bdad 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'editor', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   editor
+ * @package   core_editor
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index ed6da26..d35a18d 100644 (file)
@@ -1,30 +1,24 @@
 <?php
-
-///////////////////////////////////////////////////////////////////////////
-//                                                                       //
-// This file is part of Moodle - http://moodle.org/                      //
-// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
-//                                                                       //
-// Moodle is free software: you can redistribute it and/or modify        //
-// it under the terms of the GNU General Public License as published by  //
-// the Free Software Foundation, either version 3 of the License, or     //
-// (at your option) any later version.                                   //
-//                                                                       //
-// Moodle is distributed in the hope that it will be useful,             //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
-// GNU General Public License for more details.                          //
-//                                                                       //
-// You should have received a copy of the GNU General Public License     //
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.       //
-//                                                                       //
-///////////////////////////////////////////////////////////////////////////
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
  *
  * Strings describing subject classification (Codes are from ASCED 2001)
  *
- * @package   moodle
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 91fbf4e..23da526 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'core_enrol', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package    core
+ * @package    core_enrol
  * @subpackage enrol
  * @copyright  2010 Petr Skoda {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
index 82b3a01..963e0d4 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'error', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   error
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 53b10b3..6cc2acf 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'filters', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   filters
+ * @package   core_filters
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index feb6833..ecd7bd7 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 /**
  * Strings for component 'form', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   form
- * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @package    core
+ * @subpackage form
+ * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 $string['addfields'] = 'Add {$a} field(s) to form';
index 1d9513d..0e9438c 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'grades', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   grades
+ * @package   core_grades
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 589efa5..c0849e1 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for the advanced grading methods subsystem
  *
- * @package    core
+ * @package    core_grading
  * @subpackage grading
  * @copyright  2011 David Mudrak <david@moodle.com>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
index 63f3bb6..14060bb 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'group', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   group
+ * @package   core
  * @copyright 2006 The Open University
  * @author    J.White AT open.ac.uk
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
index 6a91a6b..753ebe4 100644 (file)
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
-
 /**
  *
  * Hub related strings
  *
- * @package   hub
+ * @package   core_hub
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index e2f0964..20ef87f 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 /**
  * Strings for component 'imscc', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   imscc
- * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @package    core
+ * @subpackage imscc
+ * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 $string['cc_import_req_dom'] = 'ERROR: The Common Cartridge import requires DOM extension.';
index 7542f00..ee6fb04 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'install', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   install
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index b80f28c..51ceee9 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
  *  - array indexes are the ISO 639-2 "T" values (terminology)
  *  - some language names are shortened
  *
- * @package   iso6392
- * @copyright 2010 onwards Martin Dougiamas  {@link http://moodle.com}
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @package    core
+ * @subpackage iso6392
+ * @copyright  2010 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 $string['aar'] = 'Afar';
index 7905f66..f44d7f9 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'langconfig', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   langconfig
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 47d4912..1c40f78 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'license', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   license
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 488cbf8..907f2dc 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'mathslib', language 'en', branch 'MOODLE_19_STABLE'
  *
- * @package   mathslib
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 9dfcc56..2e93263 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'message', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   message
+ * @package   core_message
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 64624fb..f391d1e 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -31,7 +30,7 @@
  *
  * @see       get_mimetypes_array()
  * @see       get_mimetype_description()
- * @package   mimetypes
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index d2469c8..a7051e2 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'mnet', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   mnet
+ * @package   core_mnet
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -216,6 +215,12 @@ $string['showlocal'] = 'Show local users';
 $string['showremote'] = 'Show remote users';
 $string['ssl_acl_allow'] = 'SSO ACL: Allow user \'{$a->user}\' from \'{$a->host}\'';
 $string['ssl_acl_deny'] = 'SSO ACL: Deny user \'{$a->user}\' from \'{$a->host}\'';
+$string['sslverification'] = 'SSL verification';
+$string['sslverification_help'] = 'This option allows you to configure the level of security when connecting to a peer using HTTPS.
+
+* None: no level of security
+* Verify host only: validates the domain of the SSL certificate
+* Verify host and peer (recommended): validates the domain and issuer of the SSL certificate';
 $string['ssoaccesscontrol'] = 'SSO access control';
 $string['ssoacldescr'] = 'Use this page to grant/deny access to specific users from remote MNet hosts. This is functional when you are offering SSO services to remote users. To control your <em>local</em> users\' ability to roam to other MNet hosts, use the roles system to grant them the <em>mnetlogintoremote</em> capability.';
 $string['ssoaclneeds'] = 'For this functionality to work, you must have Networking on, plus the MNet authentication plugin enabled.';
@@ -244,6 +249,8 @@ $string['userchangepasswordlink'] = '<br /> You may be able to change your passw
 $string['usernotfullysetup'] = 'Your user account is incomplete.  You need to go <a href="{$a}">back to your provider</a> and ensure your profile is completed there.  You may need to log out and in again for this to take effect.';
 $string['usersareonline'] = 'Warning: {$a} users from that server are currently logged on to your site.';
 $string['validated_by'] = 'It is validated by the network: <code>{$a}</code>';
+$string['verifyhostandpeer'] = 'Verify host and peer';
+$string['verifyhostonly'] = 'Verify host only';
 $string['verifysignature-error'] = 'The signature verification failed. An error has occurred.';
 $string['verifysignature-invalid'] = 'The signature verification failed. It appears that this payload was not signed by you.';
 $string['version'] = 'Version';
index 1974d59..4e45ae2 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'moodle', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   moodle
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 56d9d5f..ce961e3 100644 (file)
@@ -1,6 +1,26 @@
-<?php // $Id$
-      // my.php - created with Moodle 1.7 beta + (2006101003)
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
+/**
+ * Strings used by My Moodle pages.
+ *
+ * @package   core
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
 
 $string['mymoodle'] = 'My home';
 $string['nocourses'] = 'No course information to show.';
index 48aab57..95f909b 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 /**
  * Strings for component 'notes', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   notes
- * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @package    core_notes
+ * @subpackage notes
+ * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 $string['addnewnote'] = 'Add a new note';
index a969884..0237fe0 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'pagetype', language 'en'
  *
- * @package   pagetype
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 310edda..a608b01 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 /**
  * Strings for component 'pix', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   pix
- * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @package    core_pix
+ * @subpackage pix
+ * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 $string['angry'] = 'angry';
index bceee51..213eaea 100644 (file)
@@ -1,4 +1,27 @@
 <?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Strings used by the plagiarism component
+ *
+ * @package    core_plagiarism
+ * @copyright  2010 Dan Marsden <dan@danmarsden.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
 $string['availableplugins'] = 'Available plugins';
 $string['configplagiarismplugins'] = 'Please choose the plagiarism plugin you would like to configure';
 $string['enableplagiarism'] ='Enable plagiarism plugins';
index edd7cc4..b9f013f 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'portfolio', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   portfolio
+ * @package   core_portfolio
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index e19ac9f..0e7927c 100644 (file)
@@ -17,7 +17,7 @@
 /**
  * Strings for component 'question', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   question
+ * @package   core_question
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 1282b05..864c428 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'rating', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   rating
+ * @package   core_rating
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 0452ef0..082fa47 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'repository', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   repository
+ * @package   core_repository
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 32a1000..3bc7777 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'role', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   role
+ * @package   core_role
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 4e2f25a..355c392 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'search', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   search
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 02763e5..69a0a8e 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'table', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   table
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 247b7cc..4b27fc6 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'tag', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   tag
+ * @package   core_tag
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 80e58c1..01a1fea 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 /**
  * Strings for component 'timezones', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   timezones
- * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
- * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @package    core
+ * @subpackage timezones
+ * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 $string['africa/abidjan'] = 'Africa/Abidjan';
index 99b8b34..35d772c 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'userkey', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   userkey
+ * @package   core
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 8c8a47b..7617216 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,7 +17,7 @@
 /**
  * Strings for component 'webservice', language 'en', branch 'MOODLE_20_STABLE'
  *
- * @package   webservice
+ * @package   core_webservice
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index f8d12bf..01d59cc 100644 (file)
@@ -1082,7 +1082,7 @@ class block_manager {
         }
 
         // Assign roles icon.
-        if (has_capability('moodle/role:assign', $block->context)) {
+        if ($this->page->pagetype != 'my-index' && has_capability('moodle/role:assign', $block->context)) {
             //TODO: please note it is sloppy to pass urls through page parameters!!
             //      it is shortened because some web servers (e.g. IIS by default) give
             //      a 'security' error if you try to pass a full URL as a GET parameter in another URL.
index b5aeea8..516e3c5 100644 (file)
@@ -46,7 +46,7 @@ class file_temp_cleanup_task extends scheduled_task {
 
         $tmpdir = $CFG->tempdir;
         // Default to last weeks time.
-        $time = strtotime('-1 week');
+        $time = time() - ($CFG->tempdatafoldercleanup * 3600);
 
         $dir = new \RecursiveDirectoryIterator($tmpdir);
         // Show all child nodes prior to their parent.
index 6a6c9e4..9cc8ede 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="lib/db" VERSION="20141017" COMMENT="XMLDB file for core Moodle tables"
+<XMLDB PATH="lib/db" VERSION="20141201" COMMENT="XMLDB file for core Moodle tables"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
 >
         <FIELD NAME="force_theme" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="theme" TYPE="char" LENGTH="100" NOTNULL="false" SEQUENCE="false"/>
         <FIELD NAME="applicationid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="1" SEQUENCE="false"/>
+        <FIELD NAME="sslverification" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the mnet_host table"/>
       <FIELDS>
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
         <FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="component" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="The plugin this comment belongs to."/>
         <FIELD NAME="commentarea" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
         <FIELD NAME="itemid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
         <FIELD NAME="content" TYPE="text" NOTNULL="true" SEQUENCE="false"/>
index c9728de..798ea3d 100644 (file)
@@ -4058,5 +4058,34 @@ function xmldb_main_upgrade($oldversion) {
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
 
+    if ($oldversion < 2014120100.00) {
+
+        // Define field sslverification to be added to mnet_host.
+        $table = new xmldb_table('mnet_host');
+        $field = new xmldb_field('sslverification', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'applicationid');
+
+        // Conditionally launch add field sslverification.
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field);
+        }
+
+        // Main savepoint reached.
+        upgrade_main_savepoint(true, 2014120100.00);
+    }
+
+    if ($oldversion < 2014120101.00) {
+
+        // Define field component to be added to comments.
+        $table = new xmldb_table('comments');
+        $field = new xmldb_field('component', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'contextid');
+
+        // Conditionally launch add field component.
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field);
+        }
+
+        // Main savepoint reached.
+        upgrade_main_savepoint(true, 2014120101.00);
+    }
     return true;
 }
index 91d58f6..987e5c2 100644 (file)
@@ -537,45 +537,18 @@ function update_log_display_entry($module, $action, $mtable, $field) {
 }
 
 /**
- * Given some text in HTML format, this function will pass it
- * through any filters that have been configured for this context.
- *
  * @deprecated use the text formatting in a standard way instead (http://docs.moodle.org/dev/Output_functions)
  *             this was abused mostly for embedding of attachments
- * @todo final deprecation of this function in MDL-40607
- * @param string $text The text to be passed through format filters
- * @param int $courseid The current course.
- * @return string the filtered string.
  */
 function filter_text($text, $courseid = NULL) {
-    global $CFG, $COURSE;
-
-    debugging('filter_text() is deprecated, use format_text(), format_string() etc instead.', DEBUG_DEVELOPER);
-
-    if (!$courseid) {
-        $courseid = $COURSE->id;
-    }
-
-    if (!$context = context_course::instance($courseid, IGNORE_MISSING)) {
-        return $text;
-    }
-
-    return filter_manager::instance()->filter_text($text, $context);
+    throw new coding_exception('filter_text() can not be used anymore, use format_text(), format_string() etc instead.');
 }
 
 /**
- * This function indicates that current page requires the https
- * when $CFG->loginhttps enabled.
- *
- * By using this function properly, we can ensure 100% https-ized pages
- * at our entire discretion (login, forgot_password, change_password)
  * @deprecated use $PAGE->https_required() instead
- * @todo final deprecation of this function in MDL-40607
  */
 function httpsrequired() {
-    global $PAGE;
-    debugging('httpsrequired() is deprecated use $PAGE->https_required() instead.', DEBUG_DEVELOPER);
-    $PAGE->https_required();
+    throw new coding_exception('httpsrequired() can not be used any more use $PAGE->https_required() instead.');
 }
 
 /**
@@ -638,30 +611,17 @@ function get_file_url($path, $options=null, $type='coursefile') {
 }
 
 /**
- * Return all course participant for a given course
- *
  * @deprecated use get_enrolled_users($context) instead.
- * @todo final deprecation of this function in MDL-40607
- * @param integer $courseid
- * @return array of user
  */
 function get_course_participants($courseid) {
-    debugging('get_course_participants() is deprecated, use get_enrolled_users() instead.', DEBUG_DEVELOPER);
-    return get_enrolled_users(context_course::instance($courseid));
+    throw new coding_exception('get_course_participants() can not be used any more, use get_enrolled_users() instead.');
 }
 
 /**
- * Return true if the user is a participant for a given course
- *
  * @deprecated use is_enrolled($context, $userid) instead.
- * @todo final deprecation of this function in MDL-40607
- * @param integer $userid
- * @param integer $courseid
- * @return boolean
  */
 function is_course_participant($userid, $courseid) {
-    debugging('is_course_participant() is deprecated, use is_enrolled() instead.', DEBUG_DEVELOPER);
-    return is_enrolled(context_course::instance($courseid), $userid);
+    throw new coding_exception('is_course_participant() can not be used any more, use is_enrolled() instead.');
 }
 
 /**
@@ -696,25 +656,9 @@ function get_recent_enrolments($courseid, $timestart) {
 
 /**
  * @deprecated use clean_param($string, PARAM_FILE) instead.
- * @todo final deprecation of this function in MDL-40607
- *
- * @param string $string ?
- * @param int $allowdots ?
- * @return bool
  */
 function detect_munged_arguments($string, $allowdots=1) {
-    debugging('detect_munged_arguments() is deprecated, please use clean_param(,PARAM_FILE) instead.', DEBUG_DEVELOPER);
-    if (substr_count($string, '..') > $allowdots) {   // Sometimes we allow dots in references
-        return true;
-    }
-    if (preg_match('/[\|\`]/', $string)) {  // check for other bad characters
-        return true;
-    }
-    if (empty($string) or $string == '/') {
-        return true;
-    }
-
-    return false;
+    throw new coding_exception('detect_munged_arguments() can not be used any more, please use clean_param(,PARAM_FILE) instead.');
 }
 
 
@@ -860,25 +804,10 @@ function zip_files ($originalfiles, $destination) {
 }
 
 /**
- * Get the IDs for the user's groups in the given course.
- *
- * @global object
- * @param int $courseid The course being examined - the 'course' table id field.
- * @return array|bool An _array_ of groupids, or false
- * (Was return $groupids[0] - consequences!)
  * @deprecated use groups_get_all_groups() instead.
- * @todo final deprecation of this function in MDL-40607
  */
 function mygroupid($courseid) {
-    global $USER;
-
-    debugging('mygroupid() is deprecated, please use groups_get_all_groups() instead.', DEBUG_DEVELOPER);
-
-    if ($groups = groups_get_all_groups($courseid, $USER->id)) {
-        return array_keys($groups);
-    } else {
-        return false;
-    }
+    throw new coding_exception('mygroupid() can not be used any more, please use groups_get_all_groups() instead.');
 }
 
 
@@ -1022,14 +951,9 @@ function error($message, $link='') {
 
 /**
  * @deprecated use $PAGE->theme->name instead.
- * @todo final deprecation of this function in MDL-40607
- * @return string the name of the current theme.
  */
 function current_theme() {
-    global $PAGE;
-
-    debugging('current_theme() is deprecated, please use $PAGE->theme->name instead', DEBUG_DEVELOPER);
-    return $PAGE->theme->name;
+    throw new coding_exception('current_theme() can not be used any more, please use $PAGE->theme->name instead');
 }
 
 /**
@@ -1045,93 +969,31 @@ function formerr($error) {
 }
 
 /**
- * Return the markup for the destination of the 'Skip to main content' links.
- * Accessibility improvement for keyboard-only users.
- *
- * Used in course formats, /index.php and /course/index.php
- *
  * @deprecated use $OUTPUT->skip_link_target() in instead.
- * @todo final deprecation of this function in MDL-40607
- * @return string HTML element.
  */
 function skip_main_destination() {
-    global $OUTPUT;
-
-    debugging('skip_main_destination() is deprecated, please use $OUTPUT->skip_link_target() instead.', DEBUG_DEVELOPER);
-    return $OUTPUT->skip_link_target();
+    throw new coding_exception('skip_main_destination() can not be used any more, please use $OUTPUT->skip_link_target() instead.');
 }
 
 /**
- * Print a message in a standard themed container.
- *
  * @deprecated use $OUTPUT->container() instead.
- * @todo final deprecation of this function in MDL-40607
- * @param string $message, the content of the container
- * @param boolean $clearfix clear both sides
- * @param string $classes, space-separated class names.
- * @param string $idbase
- * @param boolean $return, return as string or just print it
- * @return string|void Depending on value of $return
  */
 function print_container($message, $clearfix=false, $classes='', $idbase='', $return=false) {
-    global $OUTPUT;
-
-    debugging('print_container() is deprecated. Please use $OUTPUT->container() instead.', DEBUG_DEVELOPER);
-    if ($clearfix) {
-        $classes .= ' clearfix';
-    }
-    $output = $OUTPUT->container($message, $classes, $idbase);
-    if ($return) {
-        return $output;
-    } else {
-        echo $output;
-    }
+    throw new coding_exception('print_container() can not be used any more. Please use $OUTPUT->container() instead.');
 }
 
 /**
- * Starts a container using divs
- *
  * @deprecated use $OUTPUT->container_start() instead.
- * @todo final deprecation of this function in MDL-40607
- * @param boolean $clearfix clear both sides
- * @param string $classes, space-separated class names.
- * @param string $idbase
- * @param boolean $return, return as string or just print it
- * @return string|void Based on value of $return
  */
 function print_container_start($clearfix=false, $classes='', $idbase='', $return=false) {
-    global $OUTPUT;
-
-    debugging('print_container_start() is deprecated. Please use $OUTPUT->container_start() instead.', DEBUG_DEVELOPER);
-
-    if ($clearfix) {
-        $classes .= ' clearfix';
-    }
-    $output = $OUTPUT->container_start($classes, $idbase);
-    if ($return) {
-        return $output;
-    } else {
-        echo $output;
-    }
+    throw new coding_exception('print_container_start() can not be used any more. Please use $OUTPUT->container_start() instead.');
 }
 
 /**
- * Simple function to end a container (see above)
- *
  * @deprecated use $OUTPUT->container_end() instead.
- * @todo final deprecation of this function in MDL-40607
- * @param boolean $return, return as string or just print it
- * @return string|void Based on $return
  */
 function print_container_end($return=false) {
-    global $OUTPUT;
-    debugging('print_container_end() is deprecated. Please use $OUTPUT->container_end() instead.', DEBUG_DEVELOPER);
-    $output = $OUTPUT->container_end();
-    if ($return) {
-        return $output;
-    } else {
-        echo $output;
-    }
+    throw new coding_exception('print_container_end() can not be used any more. Please use $OUTPUT->container_end() instead.');
 }
 
 /**
@@ -1161,191 +1023,36 @@ function notify($message, $classes = 'notifyproblem', $align = 'center', $return
 }
 
 /**
- * Print a continue button that goes to a particular URL.
- *
  * @deprecated use $OUTPUT->continue_button() instead.
- * @todo final deprecation of this function in MDL-40607
- *
- * @param string $link The url to create a link to.
- * @param bool $return If set to true output is returned rather than echoed, default false
- * @return string|void HTML String if return=true nothing otherwise
  */
 function print_continue($link, $return = false) {
-    global $CFG, $OUTPUT;
-
-    debugging('print_continue() is deprecated. Please use $OUTPUT->continue_button() instead.', DEBUG_DEVELOPER);
-
-    if ($link == '') {
-        if (!empty($_SERVER['HTTP_REFERER'])) {
-            $link = $_SERVER['HTTP_REFERER'];
-            $link = str_replace('&', '&amp;', $link); // make it valid XHTML
-        } else {
-            $link = $CFG->wwwroot .'/';
-        }
-    }
-
-    $output = $OUTPUT->continue_button($link);
-    if ($return) {
-        return $output;
-    } else {
-        echo $output;
-    }
+    throw new coding_exception('print_continue() can not be used any more. Please use $OUTPUT->continue_button() instead.');
 }
 
 /**
- * Print a standard header
- *
  * @deprecated use $PAGE methods instead.
- * @todo final deprecation of this function in MDL-40607
- * @param string  $title Appears at the top of the window
- * @param string  $heading Appears at the top of the page
- * @param string  $navigation Array of $navlinks arrays (keys: name, link, type) for use as breadcrumbs links
- * @param string  $focus Indicates form element to get cursor focus on load eg  inputform.password
- * @param string  $meta Meta tags to be added to the header
- * @param boolean $cache Should this page be cacheable?
- * @param string  $button HTML code for a button (usually for module editing)
- * @param string  $menu HTML code for a popup menu
- * @param boolean $usexml use XML for this page
- * @param string  $bodytags This text will be included verbatim in the <body> tag (useful for onload() etc)
- * @param bool    $return If true, return the visible elements of the header instead of echoing them.
- * @return string|void If return=true then string else void
  */
 function print_header($title='', $heading='', $navigation='', $focus='',
                       $meta='', $cache=true, $button='&nbsp;', $menu=null,
                       $usexml=false, $bodytags='', $return=false) {
-    global $PAGE, $OUTPUT;
-
-    debugging('print_header() is deprecated. Please use $PAGE methods instead.', DEBUG_DEVELOPER);
-
-    $PAGE->set_title($title);
-    $PAGE->set_heading($heading);
-    $PAGE->set_cacheable($cache);
-    if ($button == '') {
-        $button = '&nbsp;';
-    }
-    $PAGE->set_button($button);
-    $PAGE->set_headingmenu($menu);
-
-    // TODO $menu
-
-    if ($meta) {
-        throw new coding_exception('The $meta parameter to print_header is no longer supported. '.
-                'You should be able to do everything you want with $PAGE->requires and other such mechanisms.');
-    }
-    if ($usexml) {
-        throw new coding_exception('The $usexml parameter to print_header is no longer supported.');
-    }
-    if ($bodytags) {
-        throw new coding_exception('The $bodytags parameter to print_header is no longer supported.');
-    }
 
-    $output = $OUTPUT->header();
-
-    if ($return) {
-        return $output;
-    } else {
-        echo $output;
-    }
+    throw new coding_exception('print_header() can not be used any more. Please use $PAGE methods instead.');
 }
 
 /**
- * This version of print_header is simpler because the course name does not have to be
- * provided explicitly in the strings. It can be used on the site page as in courses
- * Eventually all print_header could be replaced by print_header_simple
- *
  * @deprecated use $PAGE methods instead.
- * @todo final deprecation of this function in MDL-40607
- * @param string $title Appears at the top of the window
- * @param string $heading Appears at the top of the page
- * @param string $navigation Premade navigation string (for use as breadcrumbs links)
- * @param string $focus Indicates form element to get cursor focus on load eg  inputform.password
- * @param string $meta Meta tags to be added to the header
- * @param boolean $cache Should this page be cacheable?
- * @param string $button HTML code for a button (usually for module editing)
- * @param string $menu HTML code for a popup menu
- * @param boolean $usexml use XML for this page
- * @param string $bodytags This text will be included verbatim in the <body> tag (useful for onload() etc)
- * @param bool   $return If true, return the visible elements of the header instead of echoing them.
- * @return string|void If $return=true the return string else nothing
  */
 function print_header_simple($title='', $heading='', $navigation='', $focus='', $meta='',
                        $cache=true, $button='&nbsp;', $menu='', $usexml=false, $bodytags='', $return=false) {
 
-    global $COURSE, $CFG, $PAGE, $OUTPUT;
-
-    debugging('print_header_simple() is deprecated. Please use $PAGE methods instead.', DEBUG_DEVELOPER);
-
-    if ($meta) {
-        throw new coding_exception('The $meta parameter to print_header is no longer supported. '.
-                'You should be able to do everything you want with $PAGE->requires and other such mechanisms.');
-    }
-    if ($usexml) {
-        throw new coding_exception('The $usexml parameter to print_header is no longer supported.');
-    }
-    if ($bodytags) {
-        throw new coding_exception('The $bodytags parameter to print_header is no longer supported.');
-    }
-
-    $PAGE->set_title($title);
-    $PAGE->set_heading($heading);
-    $PAGE->set_cacheable(true);
-    $PAGE->set_button($button);
-
-    $output = $OUTPUT->header();
-
-    if ($return) {
-        return $output;
-    } else {
-        echo $output;
-    }
+    throw new coding_exception('print_header_simple() can not be used any more. Please use $PAGE methods instead.');
 }
 
 /**
- * Prints a nice side block with an optional header.  The content can either
- * be a block of HTML or a list of text with optional icons.
- *
- * @static int $block_id Increments for each call to the function
- * @param string $heading HTML for the heading. Can include full HTML or just
- *   plain text - plain text will automatically be enclosed in the appropriate
- *   heading tags.
- * @param string $content HTML for the content
- * @param array $list an alternative to $content, it you want a list of things with optional icons.
- * @param array $icons optional icons for the things in $list.
- * @param string $footer Extra HTML content that gets output at the end, inside a &lt;div class="footer">
- * @param array $attributes an array of attribute => value pairs that are put on the
- * outer div of this block. If there is a class attribute ' block' gets appended to it. If there isn't
- * already a class, class='block' is used.
- * @param string $title Plain text title, as embedded in the $heading.
  * @deprecated use $OUTPUT->block() instead.
- * @todo final deprecation of this function in MDL-40607
  */
 function print_side_block($heading='', $content='', $list=NULL, $icons=NULL, $footer='', $attributes = array(), $title='') {
-    global $OUTPUT;
-
-    debugging('print_side_block() is deprecated, please use $OUTPUT->block() instead.', DEBUG_DEVELOPER);
-    // We don't use $heading, becuse it often contains HTML that we don't want.
-    // However, sometimes $title is not set, but $heading is.
-    if (empty($title)) {
-        $title = strip_tags($heading);
-    }
-
-    // Render list contents to HTML if required.
-    if (empty($content) && $list) {
-        $content = $OUTPUT->list_block_contents($icons, $list);
-    }
-
-    $bc = new block_contents();
-    $bc->content = $content;
-    $bc->footer = $footer;
-    $bc->title = $title;
-
-    if (isset($attributes['id'])) {
-        $bc->id = $attributes['id'];
-        unset($attributes['id']);
-    }
-    $bc->attributes = $attributes;
-
-    echo $OUTPUT->block($bc, BLOCK_POS_LEFT); // POS LEFT may be wrong, but no way to get a better guess here.
+    throw new coding_exception('print_side_block() can not be used any more, please use $OUTPUT->block() instead.');
 }
 
 /**
@@ -1445,7 +1152,7 @@ function editorshortcutshelpbutton() {
  * provide this function with the language strings for sortasc and sortdesc.
  *
  * @deprecated use $OUTPUT->arrow() instead.
- * @todo final deprecation of this function in MDL-40607
+ * @todo final deprecation of this function once MDL-45448 is resolved
  *
  * If no sort string is associated with the direction, an arrow with no alt text will be printed/returned.
  *
@@ -1554,66 +1261,18 @@ function choose_from_menu ($options, $name, $selected='', $nothing='choose', $sc
 }
 
 /**
- * Prints a help button about a scale
- *
  * @deprecated use $OUTPUT->help_icon_scale($courseid, $scale) instead.
- * @todo final deprecation of this function in MDL-40607
- *
- * @global object
- * @param id $courseid
- * @param object $scale
- * @param boolean $return If set to true returns rather than echo's
- * @return string|bool Depending on value of $return
  */
 function print_scale_menu_helpbutton($courseid, $scale, $return=false) {
-    global $OUTPUT;
-
-    debugging('print_scale_menu_helpbutton() is deprecated. Please use $OUTPUT->help_icon_scale($courseid, $scale) instead.', DEBUG_DEVELOPER);
-
-    $output = $OUTPUT->help_icon_scale($courseid, $scale);
-
-    if ($return) {
-        return $output;
-    } else {
-        echo $output;
-    }
+    throw new coding_exception('print_scale_menu_helpbutton() can not be used any more. '.
+        'Please use $OUTPUT->help_icon_scale($courseid, $scale) instead.');
 }
 
 /**
- * Display an standard html checkbox with an optional label
- *
  * @deprecated use html_writer::checkbox() instead.
- * @todo final deprecation of this function in MDL-40607
- *
- * @staticvar int $idcounter
- * @param string $name    The name of the checkbox
- * @param string $value   The valus that the checkbox will pass when checked
- * @param bool $checked The flag to tell the checkbox initial state
- * @param string $label   The label to be showed near the checkbox
- * @param string $alt     The info to be inserted in the alt tag
- * @param string $script If not '', then this is added to the checkbox element
- *                       as an onchange handler.
- * @param bool $return Whether this function should return a string or output
- *                     it (defaults to false)
- * @return string|void If $return=true returns string, else echo's and returns void
  */
 function print_checkbox($name, $value, $checked = true, $label = '', $alt = '', $script='', $return=false) {
-    global $OUTPUT;
-
-    debugging('print_checkbox() is deprecated. Please use html_writer::checkbox() instead.', DEBUG_DEVELOPER);
-
-    if (!empty($script)) {
-        debugging('The use of the $script param in print_checkbox has not been migrated into html_writer::checkbox().', DEBUG_DEVELOPER);
-    }
-
-    $output = html_writer::checkbox($name, $value, $checked, $label);
-
-    if (empty($return)) {
-        echo $output;
-    } else {
-        return $output;
-    }
-
+    throw new coding_exception('print_checkbox() can not be used any more. Please use html_writer::checkbox() instead.');
 }
 
 /**
@@ -1644,148 +1303,34 @@ function update_module_button($cmid, $ignored, $string) {
 }
 
 /**
- * Prints breadcrumb trail of links, called in theme/-/header.html
- *
- * This function has now been deprecated please use output's navbar method instead
- * as shown below
- *
- * <code php>
- * echo $OUTPUT->navbar();
- * </code>
- *
  * @deprecated use $OUTPUT->navbar() instead
- * @todo final deprecation of this function in MDL-40607
- * @param mixed $navigation deprecated
- * @param string $separator OBSOLETE, and now deprecated
- * @param boolean $return False to echo the breadcrumb string (default), true to return it.
- * @return string|void String or null, depending on $return.
  */
 function print_navigation ($navigation, $separator=0, $return=false) {
-    global $OUTPUT,$PAGE;
-
-    debugging('print_navigation() is deprecated, please update use $OUTPUT->navbar() instead.', DEBUG_DEVELOPER);
-
-    $output = $OUTPUT->navbar();
-
-    if ($return) {
-        return $output;
-    } else {
-        echo $output;
-    }
+    throw new coding_exception('print_navigation() can not be used any more, please update use $OUTPUT->navbar() instead.');
 }
 
 /**
- * This function will build the navigation string to be used by print_header
- * and others.
- *
- * It automatically generates the site and course level (if appropriate) links.
- *
- * If you pass in a $cm object, the method will also generate the activity (e.g. 'Forums')
- * and activityinstances (e.g. 'General Developer Forum') navigation levels.
- *
- * If you want to add any further navigation links after the ones this function generates,
- * the pass an array of extra link arrays like this:
- * array(
- *     array('name' => $linktext1, 'link' => $url1, 'type' => $linktype1),
- *     array('name' => $linktext2, 'link' => $url2, 'type' => $linktype2)
- * )
- * The normal case is to just add one further link, for example 'Editing forum' after
- * 'General Developer Forum', with no link.
- * To do that, you need to pass
- * array(array('name' => $linktext, 'link' => '', 'type' => 'title'))
- * However, becuase this is a very common case, you can use a shortcut syntax, and just
- * pass the string 'Editing forum', instead of an array as $extranavlinks.
- *
- * At the moment, the link types only have limited significance. Type 'activity' is
- * recognised in order to implement the $CFG->hideactivitytypenavlink feature. Types
- * that are known to appear are 'home', 'course', 'activity', 'activityinstance' and 'title'.
- * This really needs to be documented better. In the mean time, try to be consistent, it will
- * enable people to customise the navigation more in future.
- *
- * When passing a $cm object, the fields used are $cm->modname, $cm->name and $cm->course.
- * If you get the $cm object using the function get_coursemodule_from_instance or
- * get_coursemodule_from_id (as recommended) then this will be done for you automatically.
- * If you don't have $cm->modname or $cm->name, this fuction will attempt to find them using
- * the $cm->module and $cm->instance fields, but this takes extra database queries, so a
- * warning is printed in developer debug mode.
- *
  * @deprecated Please use $PAGE->navabar methods instead.
- * @todo final deprecation of this function in MDL-40607
- * @param mixed $extranavlinks - Normally an array of arrays, keys: name, link, type. If you
- *      only want one extra item with no link, you can pass a string instead. If you don't want
- *      any extra links, pass an empty string.
- * @param mixed $cm deprecated
- * @return array Navigation array
  */
 function build_navigation($extranavlinks, $cm = null) {
-    global $CFG, $COURSE, $DB, $SITE, $PAGE;
-
-    debugging('build_navigation() is deprecated, please use $PAGE->navbar methods instead.', DEBUG_DEVELOPER);
-    if (is_array($extranavlinks) && count($extranavlinks)>0) {
-        foreach ($extranavlinks as $nav) {
-            if (array_key_exists('name', $nav)) {
-                if (array_key_exists('link', $nav) && !empty($nav['link'])) {
-                    $link = $nav['link'];
-                } else {
-                    $link = null;
-                }
-                $PAGE->navbar->add($nav['name'],$link);
-            }
-        }
-    }
-
-    return(array('newnav' => true, 'navlinks' => array()));
+    throw new coding_exception('build_navigation() can not be used any more, please use $PAGE->navbar methods instead.');
 }
 
 /**
  * @deprecated not relevant with global navigation in Moodle 2.x+
- * @todo remove completely in MDL-40607
  */
 function navmenu($course, $cm=NULL, $targetwindow='self') {
-    // This function has been deprecated with the creation of the global nav in
-    // moodle 2.0
-    debugging('navmenu() is deprecated, it is no longer relevant with global navigation.', DEBUG_DEVELOPER);
-
-    return '';
+    throw new coding_exception('navmenu() can not be used any more, it is no longer relevant with global navigation.');
 }
 
 /// CALENDAR MANAGEMENT  ////////////////////////////////////////////////////////////////
 
 
 /**
- * Call this function to add an event to the calendar table and to call any calendar plugins
- *
- * @param object $event An object representing an event from the calendar table.
- * The event will be identified by the id field. The object event should include the following:
- *  <ul>
- *    <li><b>$event->name</b> - Name for the event
- *    <li><b>$event->description</b> - Description of the event (defaults to '')
- *    <li><b>$event->format</b> - Format for the description (using formatting types defined at the top of weblib.php)
- *    <li><b>$event->courseid</b> - The id of the course this event belongs to (0 = all courses)
- *    <li><b>$event->groupid</b> - The id of the group this event belongs to (0 = no group)
- *    <li><b>$event->userid</b> - The id of the user this event belongs to (0 = no user)
- *    <li><b>$event->modulename</b> - Name of the module that creates this event
- *    <li><b>$event->instance</b> - Instance of the module that owns this event
- *    <li><b>$event->eventtype</b> - The type info together with the module info could
- *             be used by calendar plugins to decide how to display event
- *    <li><b>$event->timestart</b>- Timestamp for start of event
- *    <li><b>$event->timeduration</b> - Duration (defaults to zero)
- *    <li><b>$event->visible</b> - 0 if the event should be hidden (e.g. because the activity that created it is hidden)
- *  </ul>
- * @return int|false The id number of the resulting record or false if failed
  * @deprecated please use calendar_event::create() instead.
- * @todo final deprecation of this function in MDL-40607
  */
  function add_event($event) {
-    global $CFG;
-    require_once($CFG->dirroot.'/calendar/lib.php');
-
-    debugging('add_event() is deprecated, please use calendar_event::create() instead.', DEBUG_DEVELOPER);
-    $event = calendar_event::create($event);
-    if ($event !== false) {
-        return $event->id;
-    }
-    return false;
+    throw new coding_exception('add_event() can not be used any more, please use calendar_event::create() instead.');
 }
 
 /**
@@ -1807,59 +1352,27 @@ function update_event($event) {
 }
 
 /**
- * Call this function to delete the event with id $id from calendar table.
- *
- * @param int $id The id of an event from the 'event' table.
- * @return bool
  * @deprecated please use calendar_event->delete() instead.
- * @todo final deprecation of this function in MDL-40607
  */
 function delete_event($id) {
-    global $CFG;
-    require_once($CFG->dirroot.'/calendar/lib.php');
-
-    debugging('delete_event() is deprecated, please use calendar_event->delete() instead.', DEBUG_DEVELOPER);
-
-    $event = calendar_event::load($id);
-    return $event->delete();
+    throw new coding_exception('delete_event() can not be used any more, please use '.
+        'calendar_event->delete() instead.');
 }
 
 /**
- * Call this function to hide an event in the calendar table
- * the event will be identified by the id field of the $event object.
- *
- * @param object $event An object representing an event from the calendar table. The event will be identified by the id field.
- * @return true
  * @deprecated please use calendar_event->toggle_visibility(false) instead.
- * @todo final deprecation of this function in MDL-40607
  */
 function hide_event($event) {
-    global $CFG;
-    require_once($CFG->dirroot.'/calendar/lib.php');
-
-    debugging('hide_event() is deprecated, please use calendar_event->toggle_visibility(false) instead.', DEBUG_DEVELOPER);
-
-    $event = new calendar_event($event);
-    return $event->toggle_visibility(false);
+    throw new coding_exception('hide_event() can not be used any more, please use '.
+        'calendar_event->toggle_visibility(false) instead.');
 }
 
 /**
- * Call this function to unhide an event in the calendar table
- * the event will be identified by the id field of the $event object.
- *
- * @param object $event An object representing an event from the calendar table. The event will be identified by the id field.
- * @return true
  * @deprecated please use calendar_event->toggle_visibility(true) instead.
- * @todo final deprecation of this function in MDL-40607
  */
 function show_event($event) {
-    global $CFG;
-    require_once($CFG->dirroot.'/calendar/lib.php');
-
-    debugging('show_event() is deprecated, please use calendar_event->toggle_visibility(true) instead.', DEBUG_DEVELOPER);
-
-    $event = new calendar_event($event);
-    return $event->toggle_visibility(true);
+    throw new coding_exception('show_event() can not be used any more, please use '.
+        'calendar_event->toggle_visibility(true) instead.');
 }
 
 /**
diff --git a/lib/editor/atto/upgrade.txt b/lib/editor/atto/upgrade.txt
new file mode 100644 (file)
index 0000000..d5267f6
--- /dev/null
@@ -0,0 +1,9 @@
+This files describes API changes in the editor_atto code.
+
+=== 2.9 ===
+
+* When adding a shortcut to the button of a plugin, atto will add a layer of validation
+to ensure that only the required keys are pressed. However, if you are using a custom
+keyConfig object you must validate the shortcut yourself. This is particularly important
+for non-English keyboard users. For more information read the documentation of
+EditorPluginButtons::_addKeyboardListener() and MDL-47133.
index cde46db..a378090 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 ecebe59..72e69db 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 3654b27..eaf01d0 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 8aad568..13cdd8f 100644 (file)
@@ -634,7 +634,11 @@ EditorPluginButtons.prototype = {
      * The keyConfig will take either an array of keyConfigurations, in
      * which case _addKeyboardListener is called multiple times; an object
      * containing an optional eventtype, optional container, and a set of
-     * keyCodes, or just a string containing the keyCodes.
+     * keyCodes, or just a string containing the keyCodes. When keyConfig is
+     * not an object, it is wrapped around a function that ensures that
+     * only the expected key modifiers were used. For instance, it checks
+     * that space+ctrl is not triggered when the user presses ctrl+shift+space.
+     * When using an object, the developer should check that manually.
      *
      * @method _addKeyboardListener
      * @param {function} callback
@@ -648,7 +652,9 @@ EditorPluginButtons.prototype = {
     _addKeyboardListener: function(callback, keyConfig, buttonName) {
         var eventtype = 'key',
             container = CSS.EDITORWRAPPER,
-            keys;
+            keys,
+            handler,
+            modifier;
 
         if (Y.Lang.isArray(keyConfig)) {
             // If an Array was specified, call the add function for each element.
@@ -669,19 +675,27 @@ EditorPluginButtons.prototype = {
 
             // Must be specified.
             keys = keyConfig.keyCodes;
+            handler = callback;
 
         } else {
-            keys = this._getKeyEvent() + keyConfig + this._getDefaultMetaKey();
+            modifier = this._getDefaultMetaKey();
+            keys = this._getKeyEvent() + keyConfig + '+' + modifier;
             if (typeof this._primaryKeyboardShortcut[buttonName] === 'undefined') {
                 this._primaryKeyboardShortcut[buttonName] = this._getDefaultMetaKeyDescription(keyConfig);
             }
 
+            // Wrap the callback into a handler to check if it uses the specified modifiers, not more.
+            handler = Y.bind(function(modifiers, e) {
+                if (this._eventUsesExactKeyModifiers(modifiers, e)) {
+                    callback.apply(this, [e]);
+                }
+            }, this, [modifier]);
         }
 
         this._buttonHandlers.push(
             this.editor.delegate(
                 eventtype,
-                callback,
+                handler,
                 keys,
                 container,
                 this
@@ -692,6 +706,34 @@ EditorPluginButtons.prototype = {
                 'debug', LOGNAME);
     },
 
+    /**
+     * Checks if a key event was strictly defined for the modifiers passed.
+     *
+     * @method _eventUsesExactKeyModifiers
+     * @param  {Array} modifiers List of key modifiers to check for (alt, ctrl, meta or shift).
+     * @param  {EventFacade} e The event facade.
+     * @return {Boolean} True if the event was stricly using the modifiers specified.
+     */
+    _eventUsesExactKeyModifiers: function(modifiers, e) {
+        var exactMatch = true,
+            hasKey;
+
+        if (e.type !== 'key') {
+            return false;
+        }
+
+        hasKey = Y.Array.indexOf(modifiers, 'alt') > -1;
+        exactMatch = exactMatch && ((e.altKey && hasKey) || (!e.altKey && !hasKey));
+        hasKey = Y.Array.indexOf(modifiers, 'ctrl') > -1;
+        exactMatch = exactMatch && ((e.ctrlKey && hasKey) || (!e.ctrlKey && !hasKey));
+        hasKey = Y.Array.indexOf(modifiers, 'meta') > -1;
+        exactMatch = exactMatch && ((e.metaKey && hasKey) || (!e.metaKey && !hasKey));
+        hasKey = Y.Array.indexOf(modifiers, 'shift') > -1;
+        exactMatch = exactMatch && ((e.shiftKey && hasKey) || (!e.shiftKey && !hasKey));
+
+        return exactMatch;
+    },
+
     /**
      * Determine if this plugin is enabled, based upon the state of it's buttons.
      *
@@ -829,9 +871,9 @@ EditorPluginButtons.prototype = {
      */
     _getDefaultMetaKey: function() {
         if (Y.UA.os === 'macintosh') {
-            return '+meta';
+            return 'meta';
         } else {
-            return '+ctrl';
+            return 'ctrl';
         }
     },
 
index 4d90789..a1d4743 100644 (file)
@@ -14,7 +14,7 @@ M.tinymce_managefiles.analysefiles = function(Y) {
     }
     if (missingfiles !== '') {
         form.addClass('hasmissingfiles')
-        form.one('.managefilesstatus').setContent(M.str.tinymce_managefiles.hasmissingfiles + ' <ul>' + missingfiles + '</ul>').addClass('error');
+        form.one('.managefilesstatus').setContent(M.util.get_string('hasmissingfiles', 'tinymce_managefiles') + ' <ul>' + missingfiles + '</ul>').addClass('error');
     }
     delfilesfieldset.all('.felement.fcheckbox').each(function(el) {
         var chb = el.one('input[type=checkbox]'),
@@ -25,6 +25,6 @@ M.tinymce_managefiles.analysefiles = function(Y) {
         }
     });
     if (missingfiles === '' && !form.hasClass('hasunusedfiles')) {
-        form.one('.managefilesstatus').setContent(M.str.tinymce_managefiles.allfilesok);
+        form.one('.managefilesstatus').setContent(M.util.get_string('allfilesok', 'tinymce_managefiles'));
     }
 }
index b53446d..e29d3c0 100644 (file)
@@ -543,10 +543,10 @@ M.form_dndupload.init = function(Y, options) {
          * @param string type - 'error' or 'info'
          */
         print_msg: function(msg, type) {
-            var header = M.str.moodle.error;
+            var header = M.util.get_string('error', 'moodle');
             if (type != 'error') {
                 type = 'info'; // one of only two types excepted
-                header = M.str.moodle.info;
+                header = M.util.get_string('info', 'moodle');
             }
             if (!this.msg_dlg) {
                 this.msg_dlg_node = Y.Node.createWithFilesSkin(M.core_filepicker.templates.message);
@@ -684,7 +684,7 @@ M.form_dndupload.init = function(Y, options) {
             node.generateID();
             var process_dlg = new Y.Panel({
                 srcNode      : node,
-                headerContent: M.str.repository.fileexistsdialogheader,
+                headerContent: M.util.get_string('fileexistsdialogheader', 'repository'),
                 zIndex       : 8000,
                 centered     : true,
                 modal        : true,
index 7f3f74f..6b01988 100644 (file)
@@ -111,7 +111,7 @@ M.form_filemanager.init = function(Y, options) {
             var labelid = 'fm-dialog-label_'+ this.selectnode.get('id');
             this.selectui = new M.core.dialogue({
                 draggable    : true,
-                headerContent: '<h3 id="' + labelid +'">' + M.str.moodle.edit + '</h3>',
+                headerContent: '<h3 id="' + labelid +'">' + M.util.get_string('edit', 'moodle') + '</h3>',
                 bodyContent  : this.selectnode,
                 centered     : true,
                 width        : '480px',
@@ -163,8 +163,8 @@ M.form_filemanager.init = function(Y, options) {
                         try {
                             data = Y.JSON.parse(o.responseText);
                         } catch(e) {
-                            scope.print_msg(M.str.repository.invalidjson, 'error');
-                            Y.error(M.str.repository.invalidjson+":\n"+o.responseText);
+                            scope.print_msg(M.util.get_string('invalidjson', 'repository'), 'error');
+                            Y.error(M.util.get_string('invalidjson', 'repository')+":\n"+o.responseText);
                             return;
                         }
                         if (data && data.tree && scope.set_current_tree) {
@@ -233,10 +233,10 @@ M.form_filemanager.init = function(Y, options) {
         },
         /** displays message in a popup */
         print_msg: function(msg, type) {
-            var header = M.str.moodle.error;
+            var header = M.util.get_string('error', 'moodle');
             if (type != 'error') {
                 type = 'info'; // one of only two types excepted
-                header = M.str.moodle.info;
+                header = M.util.get_string('info', 'moodle');
             }
             if (!this.msg_dlg) {
                 this.msg_dlg_node = Y.Node.createWithFilesSkin(M.form_filemanager.templates.message);
@@ -346,7 +346,7 @@ M.form_filemanager.init = function(Y, options) {
                     this.mkdir_dialog.show();
 
                     // Default folder name:
-                    var foldername = M.str.repository.newfolder;
+                    var foldername = M.util.get_string('newfolder', 'repository');
                     while (this.has_folder(foldername)) {
                         foldername = increment_filename(foldername, true);
                     }
@@ -391,7 +391,7 @@ M.form_filemanager.init = function(Y, options) {
                             node.set('src', obj.fileurl);
                             Y.one('body').appendChild(node);
                         } else {
-                            scope.print_msg(M.str.repository.draftareanofiles, 'error');
+                            scope.print_msg(M.util.get_string('draftareanofiles', 'repository'), 'error');
                         }
                     }
                 });
@@ -685,12 +685,12 @@ M.form_filemanager.init = function(Y, options) {
             var dialog_options = {callback:this.update_file, callbackargs:[true], scope:this};
             if (fileinfo.type == 'folder') {
                 if (!newfilename) {
-                    this.print_msg(M.str.repository.entername, 'error');
+                    this.print_msg(M.util.get_string('entername', 'repository'), 'error');
                     return;
                 }
                 if (filenamechanged || filepathchanged) {
                     if (!confirmed) {
-                        dialog_options.message = M.str.repository.confirmrenamefolder;
+                        dialog_options.message = M.util.get_string('confirmrenamefolder', 'repository');
                         this.show_confirm_dialog(dialog_options);
                         return;
                     }
@@ -699,7 +699,7 @@ M.form_filemanager.init = function(Y, options) {
                 }
             } else {
                 if (!newfilename) {
-                    this.print_msg(M.str.repository.enternewname, 'error');
+                    this.print_msg(M.util.get_string('enternewname', 'repository'), 'error');
                     return;
                 }
                 if ((filenamechanged || filepathchanged) && !confirmed && fileinfo.refcount) {
@@ -818,13 +818,13 @@ M.form_filemanager.init = function(Y, options) {
                 params.filepath = fileinfo.filepath;
                 if (fileinfo.type == 'folder') {
                     params.filename = '.';
-                    dialog_options.message = M.str.repository.confirmdeletefolder;
+                    dialog_options.message = M.util.get_string('confirmdeletefolder', 'repository');
                 } else {
                     params.filename = fileinfo.fullname;
                     if (fileinfo.refcount) {
                         dialog_options.message = M.util.get_string('confirmdeletefilewithhref', 'repository', fileinfo.refcount);
                     } else {
-                        dialog_options.message = M.str.repository.confirmdeletefile;
+                        dialog_options.message = M.util.get_string('confirmdeletefile', 'repository');
                     }
                 }
                 dialog_options.callbackargs = [params];
@@ -988,7 +988,7 @@ M.form_filemanager.init = function(Y, options) {
                                 node.original = obj.original;
                                 selectnode.one('.fp-original .fp-value').setContent(Y.Escape.html(node.original));
                             } else {
-                                selectnode.one('.fp-original .fp-value').setContent(M.str.repository.unknownsource);
+                                selectnode.one('.fp-original .fp-value').setContent(M.util.get_string('unknownsource', 'repository'));
                             }
                         }
                     }
@@ -1029,7 +1029,7 @@ M.form_filemanager.init = function(Y, options) {
             if (nodename.length > namelength) {
                 nodename = nodename.substring(0, namelength) + '...';
             }
-            Y.one('#fm-dialog-label_'+selectnode.get('id')).setContent(Y.Escape.html(M.str.moodle.edit+' '+nodename));
+            Y.one('#fm-dialog-label_'+selectnode.get('id')).setContent(Y.Escape.html(M.util.get_string('edit', 'moodle')+' '+nodename));
             // show panel
             this.selectui.show();
             Y.one('#'+selectnode.get('id')).focus();
index 853217c..9cb17d7 100644 (file)
Binary files a/lib/form/yui/build/moodle-form-showadvanced/moodle-form-showadvanced-debug.js and b/lib/form/yui/build/moodle-form-showadvanced/moodle-form-showadvanced-debug.js differ
index 4acd7a1..8cfbaa1 100644 (file)
Binary files a/lib/form/yui/build/moodle-form-showadvanced/moodle-form-showadvanced-min.js and b/lib/form/yui/build/moodle-form-showadvanced/moodle-form-showadvanced-min.js differ
index bd63778..65162a6 100644 (file)
Binary files a/lib/form/yui/build/moodle-form-showadvanced/moodle-form-showadvanced.js and b/lib/form/yui/build/moodle-form-showadvanced/moodle-form-showadvanced.js differ
index bd10a48..7663e2d 100644 (file)
@@ -82,9 +82,9 @@ Y.extend(SHOWADVANCED, Y.Base, {
         var morelesslink = Y.Node.create('<a href="#"></a>');
         morelesslink.addClass(CSS.MORELESSTOGGLER);
         if (statuselement.get('value') === '0') {
-            morelesslink.setHTML(M.str.form.showmore);
+            morelesslink.setHTML(M.util.get_string('showmore', 'form'));
         } else {
-            morelesslink.setHTML(M.str.form.showless);
+            morelesslink.setHTML(M.util.get_string('showless', 'form'));
             morelesslink.addClass(CSS.SHOWLESS);
             fieldset.all(SELECTORS.DIVFITEMADVANCED).addClass(CSS.SHOW);
         }
index 9435741..84a93d0 100644 (file)
     <licenseversion>2.0+</licenseversion>
   </library>
   <library>
-    <location>yui</location>
+    <location>yuilib</location>
     <name>YUI</name>
     <license>BSD</license>
     <version>3.17.2</version>
index 61ff1e0..8082a3c 100644 (file)
Binary files a/lib/yui/build/moodle-core-dock/moodle-core-dock-debug.js and b/lib/yui/build/moodle-core-dock/moodle-core-dock-debug.js differ
index bead75c..a83b4f4 100644 (file)
Binary files a/lib/yui/build/moodle-core-dock/moodle-core-dock-min.js and b/lib/yui/build/moodle-core-dock/moodle-core-dock-min.js differ
index de22f7f..a84d619 100644 (file)
Binary files a/lib/yui/build/moodle-core-dock/moodle-core-dock.js and b/lib/yui/build/moodle-core-dock/moodle-core-dock.js differ
index a5367fa..2305097 100644 (file)
Binary files a/lib/yui/build/moodle-core-maintenancemodetimer/moodle-core-maintenancemodetimer-debug.js and b/lib/yui/build/moodle-core-maintenancemodetimer/moodle-core-maintenancemodetimer-debug.js differ
index a2146f4..086e091 100644 (file)
Binary files a/lib/yui/build/moodle-core-maintenancemodetimer/moodle-core-maintenancemodetimer-min.js and b/lib/yui/build/moodle-core-maintenancemodetimer/moodle-core-maintenancemodetimer-min.js differ
index a5367fa..2305097 100644 (file)
Binary files a/lib/yui/build/moodle-core-maintenancemodetimer/moodle-core-maintenancemodetimer.js and b/lib/yui/build/moodle-core-maintenancemodetimer/moodle-core-maintenancemodetimer.js differ
index c1acc0a..a61cc99 100644 (file)
@@ -137,7 +137,7 @@ BLOCK.prototype = {
         blockcommands = this.cachedcontentnode.one('.title .commands').cloneNode(true);
 
         movetoimg = Y.Node.create('<img />').setAttrs({
-            alt : Y.Escape.html(M.str.block.undockitem),
+            alt : Y.Escape.html(M.util.get_string('undockitem', 'block')),
             title : Y.Escape.html(M.util.get_string('undockblock', 'block', blocktitle.get('innerHTML'))),
             src : M.util.image_url(icon, 'moodle')
         });
index ae00312..5d85886 100644 (file)
@@ -141,7 +141,8 @@ M.core.dock.fixTitleOrientation = function(title, text) {
         test,
         width,
         height,
-        container;
+        container,
+        verticaldirection = M.util.get_string('thisdirectionvertical', 'langconfig');
     title = Y.one(title);
 
     if (dock.get('orientation') !== 'vertical') {
@@ -152,10 +153,10 @@ M.core.dock.fixTitleOrientation = function(title, text) {
 
     if (Y.UA.ie > 0 && Y.UA.ie < 8) {
         // IE 6/7 can't rotate text so force ver
-        M.str.langconfig.thisdirectionvertical = 'ver';
+        verticaldirection = 'ver';
     }
 
-    switch (M.str.langconfig.thisdirectionvertical) {
+    switch (verticaldirection) {
         case 'ver':
             // Stacked is easy
             return title.set('innerHTML', text.split('').join('<br />'));
index a15177a..964aac7 100644 (file)
@@ -105,7 +105,7 @@ DOCKEDITEM.prototype = {
         dockitem.append(docktitle);
         dock.append(dockitem);
 
-        closeiconimg = create('<img alt="'+M.str.block.hidepanel+'" title="'+M.str.block.hidedockpanel+'" />');
+        closeiconimg = create('<img alt="'+M.util.get_string('hidepanel', 'block')+'" title="'+M.util.get_string('hidedockpanel', 'block')+'" />');
         closeiconimg.setAttribute('src', M.util.image_url('t/dockclose', 'moodle'));
         closeicon = create('<span class="hidepanelicon" tabindex="0"></span>').append(closeiconimg);
         closeicon.on('forceclose|click', this.hide, this);
index e8149c3..ddd352a 100644 (file)
@@ -33,7 +33,7 @@ Y.extend(MAINTENANCEMODETIMER, Y.Base, {
     updatetimer: function() {
         this.timeleftinsec -= 1;
         if (this.timeleftinsec <= 0) {
-            this.maintenancenode.set('text', M.str.admin.sitemaintenance);
+            this.maintenancenode.set('text', M.util.get_string('sitemaintenance', 'admin'));
         } else {
             var a = {};
             a.sec = this.timeleftinsec % 60;
index 5d8936b..9f72e17 100644 (file)
@@ -12,6 +12,15 @@ require_once($CFG->libdir . '/filelib.php'); // download_file_content() used her
 
 class mnet_peer {
 
+    /** No SSL verification. */
+    const SSL_NONE = 0;
+
+    /** SSL verification for host. */
+    const SSL_HOST = 1;
+
+    /** SSL verification for host and peer. */
+    const SSL_HOST_AND_PEER = 2;
+
     var $id                 = 0;
     var $wwwroot            = '';
     var $ip_address         = '';
@@ -27,6 +36,9 @@ class mnet_peer {
     var $error              = array();
     var $bootstrapped       = false; // set when the object is populated
 
+    /** @var int $sslverification The level of SSL verification to apply. */
+    public $sslverification = self::SSL_HOST_AND_PEER;
+
     function mnet_peer() {
         return true;
     }
@@ -192,6 +204,7 @@ class mnet_peer {
         $obj->force_theme           = $this->force_theme;
         $obj->theme                 = $this->theme;
         $obj->applicationid         = $this->applicationid;
+        $obj->sslverification       = $this->sslverification;
 
         if (isset($this->id) && $this->id > 0) {
             $obj->id = $this->id;
@@ -286,6 +299,7 @@ class mnet_peer {
         $this->force_theme          = $hostinfo->force_theme;
         $this->theme                = $hostinfo->theme;
         $this->applicationid        = $hostinfo->applicationid;
+        $this->sslverification      = $hostinfo->sslverification;
         $this->application = $DB->get_record('mnet_application', array('id'=>$this->applicationid));
         $this->bootstrapped = true;
     }
index 39078d2..08414cf 100644 (file)
@@ -368,8 +368,17 @@ class mnet_xmlrpc_client {
         curl_setopt($httprequest, CURLOPT_POST, true);
         curl_setopt($httprequest, CURLOPT_USERAGENT, 'Moodle');
         curl_setopt($httprequest, CURLOPT_HTTPHEADER, array("Content-Type: text/xml charset=UTF-8"));
-        curl_setopt($httprequest, CURLOPT_SSL_VERIFYPEER, false);
-        curl_setopt($httprequest, CURLOPT_SSL_VERIFYHOST, 0);
+
+        $verifyhost = 0;
+        $verifypeer = false;
+        if ($mnet_peer->sslverification == mnet_peer::SSL_HOST_AND_PEER) {
+            $verifyhost = 2;
+            $verifypeer = true;
+        } else if ($mnet_peer->sslverification == mnet_peer::SSL_HOST) {
+            $verifyhost = 2;
+        }
+        curl_setopt($httprequest, CURLOPT_SSL_VERIFYHOST, $verifyhost);
+        curl_setopt($httprequest, CURLOPT_SSL_VERIFYPEER, $verifypeer);
         return $httprequest;
     }
 }
index 8215069..28453e7 100644 (file)
@@ -141,7 +141,7 @@ M.mod_chat_ajax.init = function(Y, cfg) {
 
         send : function(e, beep) {
             if((this.messageinput.get('value') != '') || (typeof beep != 'undefined')) {
-                this.sendbutton.set('value', M.str.chat.sending);
+                this.sendbutton.set('value', M.util.get_string('sending', 'chat'));
                 var data = {
                     chat_message : (!beep) ? this.messageinput.get('value') : '',
                     chat_sid : this.cfg.sid,
@@ -169,7 +169,7 @@ M.mod_chat_ajax.init = function(Y, cfg) {
             } catch (ex) {
                 return;
             }
-            this.sendbutton.set('value', M.str.chat.send);
+            this.sendbutton.set('value', M.util.get_string('send', 'chat'));
             this.messageinput.set('value', '');
             clearInterval(this.interval);
             this.update_messages();
@@ -243,9 +243,9 @@ M.mod_chat_ajax.init = function(Y, cfg) {
                     li.all('td').item(1).append(Y.Node.create('<strong><a target="_blank" href="' + users[i].url + '">' + users[i].name + '</a></strong>'));
                 } else {
                     li.all('td').item(1).append(Y.Node.create('<div><a target="_blank" href="' + users[i].url + '">' + users[i].name + '</a></div>'));
-                    var talk = Y.Node.create('<a href="###">' + M.str.chat.talk + '</a>');
+                    var talk = Y.Node.create('<a href="###">' + M.util.get_string('talk', 'chat') + '</a>');
                     talk.on('click', this.talkto, this, users[i].name);
-                    var beep = Y.Node.create('<a href="###">' + M.str.chat.beep + '</a>');
+                    var beep = Y.Node.create('<a href="###">' + M.util.get_string('beep', 'chat') + '</a>');
                     beep.on('click', this.send, this, users[i].id);
                     li.all('td').item(1).append(Y.Node.create('<div></div>').append(talk).append('&nbsp;').append(beep));
                 }
index 38770ae..492f6a9 100644 (file)
@@ -105,6 +105,8 @@ $string['configshortpost'] = 'Any post under this length (in characters not incl
 $string['configtrackingtype'] = 'Default setting for read tracking.';
 $string['configtrackreadposts'] = 'Set to \'yes\' if you want to track read/unread for each user.';
 $string['configusermarksread'] = 'If \'yes\', the user must manually mark a post as read. If \'no\', when the post is viewed it is marked as read.';
+$string['confirmsubscribediscussion'] = 'Do you really want to subscribe to discussion \'{$a->discussion}\' in forum \'{$a->forum}\'?';
+$string['confirmunsubscribediscussion'] = 'Do you really want to unsubscribe from discussion \'{$a->discussion}\' in forum \'{$a->forum}\'?';
 $string['confirmsubscribe'] = 'Do you really want to subscribe to forum \'{$a}\'?';
 $string['confirmunsubscribe'] = 'Do you really want to unsubscribe from forum \'{$a}\'?';
 $string['couldnotadd'] = 'Could not add your post due to an unknown error';
@@ -115,7 +117,6 @@ $string['delete'] = 'Delete';
 $string['deleteddiscussion'] = 'The discussion topic has been deleted';
 $string['deletedpost'] = 'The post has been deleted';
 $string['deletedposts'] = 'Those posts have been deleted';
-$string['deleteoriginalonreply'] = 'If replying directly to this via email, please do not include a quoted copy of the post you are responding to';
 $string['deletesure'] = 'Are you sure you want to delete this post?';
 $string['deletesureplural'] = 'Are you sure you want to delete this post and all replies? ({$a} posts)';
 $string['digestmailheader'] = 'This is your daily digest of new posts from the {$a->sitename} forums. To change your default forum email preferences, go to {$a->userprefs}.';
@@ -408,7 +409,7 @@ $string['repliesmany'] = '{$a} replies so far';
 $string['repliesone'] = '{$a} reply so far';
 $string['reply'] = 'Reply';
 $string['replyforum'] = 'Reply to forum';
-$string['replytoforumpost'] = 'You can reply to this forum post by email.';
+$string['replytopostbyemail'] = 'If you reply to this via email, don\'t include a quoted copy of this post. ';
 $string['replytouser'] = 'Use email address in reply';
 $string['reply_handler'] = 'Reply to forum posts via email';
 $string['reply_handler_name'] = 'Reply to forum posts';
@@ -446,6 +447,7 @@ $string['smallmessage'] = '{$a->user} posted in {$a->forumname}';
 $string['startedby'] = 'Started by';
 $string['subject'] = 'Subject';
 $string['subscribe'] = 'Subscribe to this forum';
+$string['subscribediscussion'] = 'Subscribe to this discussion';
 $string['subscribeall'] = 'Subscribe everyone to this forum';
 $string['subscribeenrolledonly'] = 'Sorry, only enrolled users are allowed to subscribe to forum post notifications.';
 $string['subscribed'] = 'Subscribed';
index fc81e87..481fc71 100644 (file)
@@ -762,7 +762,7 @@ function forum_cron() {
                 $a->courseshortname = $shortname;
                 $a->forumname = $cleanforumname;
                 $a->subject = format_string($post->subject, true);
-                $postsubject = html_to_text(get_string('postmailsubject', 'forum', $a));
+                $postsubject = html_to_text(get_string('postmailsubject', 'forum', $a), 0);
                 $posttext = forum_make_mail_text($course, $cm, $forum, $discussion, $post, $userfrom, $userto, false,
                         $replyaddress);
                 $posthtml = forum_make_mail_html($course, $cm, $forum, $discussion, $post, $userfrom, $userto,
@@ -1186,10 +1186,6 @@ function forum_make_mail_text($course, $cm, $forum, $discussion, $post, $userfro
 
     $posttext = '';
 
-    if ($replyaddress) {
-        $posttext .= "--" . get_string('deleteoriginalonreply', 'mod_forum') . "--\n";
-    }
-
     if (!$bare) {
         $shortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
         $posttext  .= "$shortname -> $strforums -> ".format_string($forum->name,true);
@@ -1241,7 +1237,7 @@ function forum_make_mail_text($course, $cm, $forum, $discussion, $post, $userfro
     $posttext .= ": {$CFG->wwwroot}/mod/forum/index.php?id={$forum->course}\n";
 
     if ($replyaddress) {
-        $posttext .= "\n\n" . get_string('replytoforumpost', 'mod_forum');
+        $posttext .= "\n\n" . get_string('replytopostbyemail', 'mod_forum');
     }
 
     return $posttext;
@@ -1286,10 +1282,6 @@ function forum_make_mail_html($course, $cm, $forum, $discussion, $post, $userfro
     $posthtml .= '</head>';
     $posthtml .= "\n<body id=\"email\">\n\n";
 
-    if ($replyaddress) {
-        $posthtml .= "<p><em>--" . get_string('deleteoriginalonreply', 'mod_forum') . "--</em></p>";
-    }
-
     $posthtml .= '<div class="navbar">'.
     '<a target="_blank" href="'.$CFG->wwwroot.'/course/view.php?id='.$course->id.'">'.$shortname.'</a> &raquo; '.
     '<a target="_blank" href="'.$CFG->wwwroot.'/mod/forum/index.php?id='.$course->id.'">'.$strforums.'</a> &raquo; '.
@@ -1303,7 +1295,7 @@ function forum_make_mail_html($course, $cm, $forum, $discussion, $post, $userfro
     $posthtml .= forum_make_mail_post($course, $cm, $forum, $discussion, $post, $userfrom, $userto, false, $canreply, true, false);
 
     if ($replyaddress) {
-        $posthtml .= html_writer::tag('p', get_string('replytoforumpost', 'mod_forum'));
+        $posthtml .= html_writer::tag('p', get_string('replytopostbyemail', 'mod_forum'));
     }
 
     $footerlinks = array();
@@ -7055,6 +7047,11 @@ function forum_extend_settings_navigation(settings_navigation $settingsnav, navi
         $PAGE->cm->context = context_module::instance($PAGE->cm->instance);
     }
 
+    $params = $PAGE->url->params();
+    if (!empty($params['d'])) {
+        $discussionid = $params['d'];
+    }
+
     // for some actions you need to be enrolled, beiing admin is not enough sometimes here
     $enrolled = is_enrolled($PAGE->cm->context, $USER, '', false);
     $activeenrolled = is_enrolled($PAGE->cm->context, $USER, '', true);
@@ -7110,13 +7107,28 @@ function forum_extend_settings_navigation(settings_navigation $settingsnav, navi
     }
 
     if ($cansubscribe) {
-        if (\mod_forum\subscriptions::is_subscribed($USER->id, $forumobject)) {
+        if (\mod_forum\subscriptions::is_subscribed($USER->id, $forumobject, null, $PAGE->cm)) {
             $linktext = get_string('unsubscribe', 'forum');
         } else {
             $linktext = get_string('subscribe', 'forum');
         }
         $url = new moodle_url('/mod/forum/subscribe.php', array('id'=>$forumobject->id, 'sesskey'=>sesskey()));
         $forumnode->add($linktext, $url, navigation_node::TYPE_SETTING);
+
+        if (isset($discussionid)) {
+            if (\mod_forum\subscriptions::is_subscribed($USER->id, $forumobject, $discussionid, $PAGE->cm)) {
+                $linktext = get_string('unsubscribediscussion', 'forum');
+            } else {
+                $linktext = get_string('subscribediscussion', 'forum');
+            }
+            $url = new moodle_url('/mod/forum/subscribe.php', array(
+                    'id' => $forumobject->id,
+                    'sesskey' => sesskey(),
+                    'd' => $discussionid,
+                    'returnurl' => $PAGE->url->out(),
+                ));
+            $forumnode->add($linktext, $url, navigation_node::TYPE_SETTING);
+        }
     }
 
     if (has_capability('mod/forum:viewsubscribers', $PAGE->cm->context)){
index 9b1d9ba..a18010c 100644 (file)
@@ -51,6 +51,10 @@ if ($user !== 0) {
 if (!is_null($sesskey)) {
     $url->param('sesskey', $sesskey);
 }
+if (!is_null($discussionid)) {
+    $url->param('d', $discussionid);
+    $discussion = $DB->get_record('forum_discussions', array('id' => $discussionid), '*', MUST_EXIST);
+}
 $PAGE->set_url($url);
 
 $forum   = $DB->get_record('forum', array('id' => $id), '*', MUST_EXIST);
@@ -147,12 +151,23 @@ $info->name  = fullname($user);
 $info->forum = format_string($forum->name);
 
 if ($issubscribed) {
-    if (is_null($sesskey)) {    // we came here via link in email
+    if (is_null($sesskey)) {
+        // We came here via link in email.
         $PAGE->set_title($course->shortname);
         $PAGE->set_heading($course->fullname);
         echo $OUTPUT->header();
-        echo $OUTPUT->confirm(get_string('confirmunsubscribe', 'forum', format_string($forum->name)),
-                new moodle_url($PAGE->url, array('sesskey' => sesskey())), new moodle_url('/mod/forum/view.php', array('f' => $id)));
+
+        $viewurl = new moodle_url('/mod/forum/view.php', array('f' => $id));
+        if ($discussionid) {
+            $a = new stdClass();
+            $a->forum = format_string($forum->name);
+            $a->discussion = format_string($discussion->name);
+            echo $OUTPUT->confirm(get_string('confirmunsubscribediscussion', 'forum', $a),
+                    $PAGE->url, $viewurl);
+        } else {
+            echo $OUTPUT->confirm(get_string('confirmunsubscribe', 'forum', format_string($forum->name)),
+                    $PAGE->url, $viewurl);
+        }
         echo $OUTPUT->footer();
         exit;
     }
@@ -164,7 +179,6 @@ if ($issubscribed) {
             print_error('cannotunsubscribe', 'forum', $_SERVER["HTTP_REFERER"]);
         }
     } else {
-        $discussion = $DB->get_record('forum_discussions', array('id' => $discussionid));
         if (\mod_forum\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion, $context)) {
             $info->discussion = $discussion->name;
             redirect($returnto, get_string("discussionnownotsubscribed", "forum", $info), 1);
@@ -180,12 +194,23 @@ if ($issubscribed) {
     if (!has_capability('mod/forum:viewdiscussion', $context)) {
         print_error('noviewdiscussionspermission', 'forum', $_SERVER["HTTP_REFERER"]);
     }
-    if (is_null($sesskey)) {    // we came here via link in email
+    if (is_null($sesskey)) {
+        // We came here via link in email.
         $PAGE->set_title($course->shortname);
         $PAGE->set_heading($course->fullname);
         echo $OUTPUT->header();
-        echo $OUTPUT->confirm(get_string('confirmsubscribe', 'forum', format_string($forum->name)),
-                new moodle_url($PAGE->url, array('sesskey' => sesskey())), new moodle_url('/mod/forum/view.php', array('f' => $id)));
+
+        $viewurl = new moodle_url('/mod/forum/view.php', array('f' => $id));
+        if ($discussionid) {
+            $a = new stdClass();
+            $a->forum = format_string($forum->name);
+            $a->discussion = format_string($discussion->name);
+            echo $OUTPUT->confirm(get_string('confirmsubscribediscussion', 'forum', $a),
+                    $PAGE->url, $viewurl);
+        } else {
+            echo $OUTPUT->confirm(get_string('confirmsubscribe', 'forum', format_string($forum->name)),
+                    $PAGE->url, $viewurl);
+        }
         echo $OUTPUT->footer();
         exit;
     }
@@ -194,7 +219,6 @@ if ($issubscribed) {
         \mod_forum\subscriptions::subscribe_user($user->id, $forum, $context, true);
         redirect($returnto, get_string("nowsubscribed", "forum", $info), 1);
     } else {
-        $discussion = $DB->get_record('forum_discussions', array('id' => $discussionid));
         $info->discussion = $discussion->name;
         \mod_forum\subscriptions::subscribe_user_to_discussion($user->id, $discussion, $context);
         redirect($returnto, get_string("discussionnowsubscribed", "forum", $info), 1);
index 8fc5c13..f7f4e71 100644 (file)
@@ -304,3 +304,49 @@ Feature: A user can control their own subscription preferences for a discussion
    And I follow "Test post subject one"
    And "You are not subscribed to this discussion. Click to subscribe." "link" should not exist
    And "You are subscribed to this discussion. Click to unsubscribe." "link" should not exist
+
+  Scenario: A user can toggle their subscription preferences when viewing a discussion
+    Given I add a "Forum" to section "1" and I fill the form with:
+      | Forum name        | Test forum name |
+      | Forum type        | Standard forum for general use |
+      | Description       | Test forum description |
+      | Subscription mode | Optional subscription |
+    And I add a new discussion to "Test forum name" forum with:
+      | Subject | Test post subject one |
+      | Message | Test post message one |
+    And I log out
+    And I log in as "student1"
+    And I follow "Course 1"
+    And I follow "Test forum name"
+    When I follow "Test post subject one"
+    Then I should see "Subscribe to this forum"
+    And I should see "Subscribe to this discussion"
+    And I follow "Subscribe to this forum"
+    And I follow "Continue"
+    And I follow "Test post subject one"
+    And I should see "Unsubscribe from this forum"
+    And I should see "Unsubscribe from this discussion"
+    And I follow "Unsubscribe from this discussion"
+    And I follow "Continue"
+    And I follow "Test post subject one"
+    And I should see "Unsubscribe from this forum"
+    And I should see "Subscribe to this discussion"
+    And I follow "Unsubscribe from this forum"
+    And I follow "Continue"
+    And I follow "Test post subject one"
+    And I should see "Subscribe to this forum"
+    And I should see "Subscribe to this discussion"
+    And I follow "Subscribe to this discussion"
+    And I follow "Continue"
+    And I should see "Subscribe to this forum"
+    And I should see "Unsubscribe from this discussion"
+    And I follow "Subscribe to this forum"
+    And I follow "Continue"
+    And I follow "Test post subject one"
+    And I should see "Unsubscribe from this forum"
+    And I should see "Unsubscribe from this discussion"
+    And I follow "Unsubscribe from this forum"
+    And I follow "Continue"
+    And I follow "Test post subject one"
+    And I should see "Subscribe to this forum"
+    And I should see "Subscribe to this discussion"
index 2f6d814..f7946f1 100644 (file)
@@ -119,14 +119,15 @@ class mod_forum_mail_testcase extends advanced_testcase {
      *
      * @param stdClass $forum The forum to post in
      * @param stdClass $author The author to post as
+     * @param array $fields any other fields in discussion (name, message, messageformat, ...)
      * @param array An array containing the discussion object, and the post object
      */
-    protected function helper_post_to_forum($forum, $author) {
+    protected function helper_post_to_forum($forum, $author, $fields = array()) {
         global $DB;
         $generator = $this->getDataGenerator()->get_plugin_generator('mod_forum');
 
         // Create a discussion in the forum, and then add a post to that discussion.
-        $record = new stdClass();
+        $record = (object)$fields;
         $record->course = $forum->course;
         $record->userid = $author->id;
         $record->forum = $forum->id;
@@ -807,4 +808,29 @@ class mod_forum_mail_testcase extends advanced_testcase {
             $this->assertRegExp('/Reply-To: moodlemoodle123\+[^@]*@example.com/', $message->header);
         }
     }
+
+    public function test_long_subject() {
+        $this->resetAfterTest(true);
+
+        // Create a course, with a forum.
+        $course = $this->getDataGenerator()->create_course();
+
+        $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE);
+        $forum = $this->getDataGenerator()->create_module('forum', $options);
+
+        // Create a user enrolled in the course as student.
+        list($author) = $this->helper_create_users($course, 1);
+
+        // Post a discussion to the forum.
+        $subject = 'This is the very long forum post subject that somebody was very kind of leaving, it is intended to check if long subject comes in mail correctly. Thank you.';
+        $a = (object)array('courseshortname' => $course->shortname, 'forumname' => $forum->name, 'subject' => $subject);
+        $expectedsubject = get_string('postmailsubject', 'forum', $a);
+        list($discussion, $post) = $this->helper_post_to_forum($forum, $author, array('name' => $subject));
+
+        // Run cron and check that the expected number of users received the notification.
+        $messages = $this->helper_run_cron_check_count($post, 1);
+        $message = reset($messages);
+        $this->assertEquals($author->id, $message->useridfrom);
+        $this->assertEquals($expectedsubject, $message->subject);
+    }
 }
index 8933d56..c4f226a 100644 (file)
@@ -188,14 +188,14 @@ M.mod_imscp.init = function(Y) {
 
 
         // layout
-        Y.YUI2.widget.LayoutUnit.prototype.STR_COLLAPSE = M.str.moodle.hide;
-        Y.YUI2.widget.LayoutUnit.prototype.STR_EXPAND = M.str.moodle.show;
+        Y.YUI2.widget.LayoutUnit.prototype.STR_COLLAPSE = M.util.get_string('hide', 'moodle');
+        Y.YUI2.widget.LayoutUnit.prototype.STR_EXPAND = M.util.get_string('show', 'moodle');
 
         imscp_layout_widget = new Y.YUI2.widget.Layout('imscp_layout', {
             minWidth: 600,
             minHeight: 400,
             units: [
-                { position: 'left', body: 'imscp_toc', header: M.str.imscp.toc, width: 250, resize: true, gutter: '2px 5px 5px 2px', collapse: true, minWidth:150},
+                { position: 'left', body: 'imscp_toc', header: M.util.get_string('toc', 'imscp'), width: 250, resize: true, gutter: '2px 5px 5px 2px', collapse: true, minWidth:150},
                 { position: 'center', body: '<div id="imscp_content"></div>', gutter: '2px 5px 5px 2px', scroll: true}
             ]
         });
index 76d56e3..f6c13dd 100644 (file)
@@ -587,7 +587,8 @@ class qformat_default {
     /// this format, this function converts it into a question
     /// object suitable for processing and insertion into Moodle.
 
-        echo "<p>This flash question format has not yet been completed!</p>";
+        // We should never get there unless the qformat plugin is broken.
+        throw new coding_exception('Question format plugin is missing important code: readquestion.');
 
         return null;
     }
index 306b90f..8a7c034 100644 (file)
                 var domainRegex = /(?:https?:\/\/)?(?:www\.)?([^\/]+)(?:\/|$)/i;
                 var match = domainRegex.exec(url);
                 if(match && match[1] && match[1].toLowerCase() === selectedOption.getAttribute('domain').toLowerCase()){
-                    automatchToolDisplay.set('innerHTML',  '<img style="vertical-align:text-bottom" src="' + self.settings.green_check_icon_url + '" />' + M.str.lti.using_tool_configuration + selectedOption.get('text'));
+                    automatchToolDisplay.set('innerHTML',  '<img style="vertical-align:text-bottom" src="' + self.settings.green_check_icon_url + '" />' + M.util.get_string('using_tool_configuration', 'lti') + selectedOption.get('text'));
                 } else {
                     // The entered URL does not match the domain of the tool configuration
-                    automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.warning_icon_url + '" />' + M.str.lti.domain_mismatch);
+                    automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.warning_icon_url + '" />' + M.util.get_string('domain_mismatch', 'lti'));
                 }
             }
 
             // Indicate the tool is manually configured
             // We still check the Launch URL with the server as course/site tools may override privacy settings
             if(key.get('value') !== '' && secret.get('value') !== ''){
-                automatchToolDisplay.set('innerHTML',  '<img style="vertical-align:text-bottom" src="' + self.settings.green_check_icon_url + '" />' + M.str.lti.custom_config);
+                automatchToolDisplay.set('innerHTML',  '<img style="vertical-align:text-bottom" src="' + self.settings.green_check_icon_url + '" />' + M.util.get_string('custom_config', 'lti'));
             }
 
             var continuation = function(toolInfo, inputfield){
                     self.updatePrivacySettings(toolInfo);
                 }
                 if(toolInfo.toolname){
-                    automatchToolDisplay.set('innerHTML',  '<img style="vertical-align:text-bottom" src="' + self.settings.green_check_icon_url + '" />' + M.str.lti.using_tool_configuration + toolInfo.toolname);
+                    automatchToolDisplay.set('innerHTML',  '<img style="vertical-align:text-bottom" src="' + self.settings.green_check_icon_url + '" />' + M.util.get_string('using_tool_configuration', 'lti') + toolInfo.toolname);
                 } else if(!selectedToolType) {
                     // Inform them custom configuration is in use
                     if(key.get('value') === '' || secret.get('value') === ''){
-                        automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.warning_icon_url + '" />' + M.str.lti.tool_config_not_found);
+                        automatchToolDisplay.set('innerHTML', '<img style="vertical-align:text-bottom" src="' + self.settings.warning_icon_url + '" />' + M.util.get_string('tool_config_not_found', 'lti'));
                     }
                 }
             };
                     if(settingValue == M.mod_lti.LTI_SETTING_NEVER){
                         control.set('disabled', true);
                         control.set('checked', false);
-                        control.set('title', M.str.lti.forced_help);
+                        control.set('title', M.util.get_string('forced_help', 'lti'));
                     } else if(settingValue == M.mod_lti.LTI_SETTING_ALWAYS){
                         control.set('disabled', true);
                         control.set('checked', true);
-                        control.set('title', M.str.lti.forced_help);
+                        control.set('title', M.util.get_string('forced_help', 'lti'));
                     } else if(settingValue == M.mod_lti.LTI_SETTING_DELEGATE){
                         control.set('disabled', false);
 
 
                 var globalGroup = Y.Node.create('<optgroup />')
                                     .set('id', 'global_tool_group')
-                                    .set('label', M.str.lti.global_tool_types);
+                                    .set('label', M.util.get_string('global_tool_types', 'lti'));
 
                 var courseGroup = Y.Node.create('<optgroup />')
                                     .set('id', 'course_tool_group')
-                                    .set('label', M.str.lti.course_tool_types);
+                                    .set('label', M.util.get_string('course_tool_types', 'lti'));
 
                 var globalOptions = typeSelector.all('option[globalTool=1]').remove().each(function(node){
                     globalGroup.append(node);
                         .append(Y.Node.create('<img src="' + iconUrl + '" />'));
             }
 
-            var addIcon = createIcon('lti_add_tool_type', M.str.lti.addtype, this.settings.add_icon_url);
-            var editIcon = createIcon('lti_edit_tool_type', M.str.lti.edittype, this.settings.edit_icon_url);
-            var deleteIcon  = createIcon('lti_delete_tool_type', M.str.lti.deletetype, this.settings.delete_icon_url);
+            var addIcon = createIcon('lti_add_tool_type', M.util.get_string('addtype', 'lti'), this.settings.add_icon_url);
+            var editIcon = createIcon('lti_edit_tool_type', M.util.get_string('edittype', 'lti'), this.settings.edit_icon_url);
+            var deleteIcon  = createIcon('lti_delete_tool_type', M.util.get_string('deletetype', 'lti'), this.settings.delete_icon_url);
 
             editIcon.on('click', function(e){
                 var toolTypeId = typeSelector.get('value');
  &nbs