Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

MDL-22414 Merge branch 'master' into backup-convert

Conflicts:
	theme/base/style/core.css
  • Loading branch information...
commit b61cf3ff8a3467a9245325f5157c1b20e090c116 2 parents fad0f24 + 6911fa1
@mudrd8mz mudrd8mz authored
Showing with 11,966 additions and 6,319 deletions.
  1. +1 −1  admin/generator.php
  2. +0 −1  admin/index.php
  3. +70 −0 admin/message.php
  4. +248 −226 admin/qtypes.php
  5. +2 −2 admin/registration/confirmregistration.php
  6. +2 −2 admin/registration/index.php
  7. +5 −3 admin/report/questioninstances/index.php
  8. +1 −1  admin/report/spamcleaner/module.js
  9. +1 −1  admin/roles/module.js
  10. +2 −0  admin/settings/appearance.php
  11. +3 −3 admin/settings/courses.php
  12. +24 −0 admin/settings/plugins.php
  13. +2 −51 admin/settings/server.php
  14. +2 −2 admin/webservice/service_user_settings.php
  15. +2 −2 admin/webservice/testclient.php
  16. +1 −1  admin/webservice/tokens.php
  17. +1 −2  backup/moodle2/backup_qtype_plugin.class.php
  18. +64 −53 backup/moodle2/backup_stepslib.php
  19. +24 −4 backup/moodle2/restore_qtype_plugin.class.php
  20. +157 −47 backup/moodle2/restore_stepslib.php
  21. +50 −23 enrol/externallib.php
  22. +14 −27 lang/en/admin.php
  23. +1 −0  lang/en/error.php
  24. +17 −1 lang/en/message.php
  25. +3 −3 lang/en/moodle.php
  26. +2 −0  lang/en/notes.php
  27. +137 −0 lang/en/question.php
  28. +3 −0  lang/en/webservice.php
  29. +458 −6 lib/adminlib.php
  30. +2 −2 lib/cronlib.php
  31. +93 −14 lib/db/install.xml
  32. +4 −0 lib/db/messages.php
  33. +44 −0 lib/db/services.php
  34. +432 −0 lib/db/upgrade.php
  35. +51 −0 lib/db/upgradelib.php
  36. +2 −0  lib/html2text.php
  37. +0 −1  lib/installlib.php
  38. +191 −85 lib/messagelib.php
  39. +176 −27 lib/moodlelib.php
  40. +38 −2 lib/outputrenderers.php
  41. +1 −0  lib/outputrequirementslib.php
  42. +39 −34 lib/pagelib.php
  43. +506 −1,939 lib/questionlib.php
  44. +6 −1 lib/resourcelib.php
  45. +296 −1 lib/simpletest/testmoodlelib.php
  46. +38 −118 lib/simpletest/testquestionlib.php
  47. +4 −3 lib/simpletest/testweblib.php
  48. +37 −0 lib/upgradelib.php
  49. +21 −2 lib/weblib.php
  50. +48 −0 local/qeupgradehelper/README.txt
  51. +162 −0 local/qeupgradehelper/afterupgradelib.php
  52. +76 −0 local/qeupgradehelper/convertquiz.php
  53. +69 −0 local/qeupgradehelper/cronsetup.php
  54. +62 −0 local/qeupgradehelper/cronsetup_form.php
  55. +74 −0 local/qeupgradehelper/extracttestcase.php
  56. +62 −0 local/qeupgradehelper/extracttestcase_form.php
  57. +55 −0 local/qeupgradehelper/index.php
  58. +83 −0 local/qeupgradehelper/lang/en/local_qeupgradehelper.php
  59. +74 −0 local/qeupgradehelper/lib.php
  60. +61 −0 local/qeupgradehelper/listpreupgrade.php
  61. +49 −0 local/qeupgradehelper/listtodo.php
  62. +50 −0 local/qeupgradehelper/listupgraded.php
  63. +661 −0 local/qeupgradehelper/locallib.php
  64. +115 −0 local/qeupgradehelper/partialupgrade-example.php
  65. +168 −0 local/qeupgradehelper/renderer.php
  66. +72 −0 local/qeupgradehelper/resetquiz.php
  67. +32 −0 local/qeupgradehelper/settings.php
  68. +6 −0 local/qeupgradehelper/styles.css
  69. +29 −0 local/qeupgradehelper/version.php
  70. +115 −0 message/defaultoutputs.php
  71. +30 −121 message/edit.php
  72. +159 −0 message/externallib.php
  73. +283 −88 message/lib.php
  74. +46 −1 message/module.js
  75. +16 −1 message/output/email/lang/en/message_email.php
  76. +1 −1  message/output/email/message_output_email.php
  77. +44 −0 message/output/email/settings.php
  78. +11 −1 message/output/jabber/lang/en/message_jabber.php
  79. +51 −41 message/output/jabber/message_output_jabber.php
  80. +34 −0 message/output/jabber/settings.php
  81. +16 −0 message/output/lib.php
  82. +346 −0 message/renderer.php
  83. +2 −4 mod/assignment/lib.php
  84. +2 −0  mod/forum/lang/en/forum.php
  85. +6 −3 mod/forum/settings.php
  86. +1 −1  mod/glossary/backup/moodle2/backup_glossary_stepslib.php
  87. +142 −85 mod/quiz/accessrules.php
  88. +27 −5 mod/quiz/addrandom.php
  89. +45 −9 mod/quiz/addrandomform.php
  90. +116 −156 mod/quiz/attempt.php
  91. +619 −603 mod/quiz/attemptlib.php
  92. +13 −7 mod/quiz/backup/moodle2/backup_quiz_activity_task.class.php
  93. +25 −15 mod/quiz/backup/moodle2/backup_quiz_stepslib.php
  94. +84 −49 mod/quiz/backup/moodle2/restore_quiz_activity_task.class.php
  95. +127 −20 mod/quiz/backup/moodle2/restore_quiz_stepslib.php
  96. +62 −52 mod/quiz/comment.php
  97. +22 −1 mod/quiz/db/access.php
  98. +32 −8 mod/quiz/db/install.php
  99. +63 −54 mod/quiz/db/install.xml
  100. +1 −2  mod/quiz/db/log.php
  101. +10 −13 mod/quiz/db/messages.php
  102. +26 −1 mod/quiz/db/subplugins.php
  103. +725 −103 mod/quiz/db/upgrade.php
  104. +76 −0 mod/quiz/db/upgradelib.php
  105. +32 −15 mod/quiz/edit.js
  106. +117 −88 mod/quiz/edit.php
  107. +354 −280 mod/quiz/editlib.php
  108. +51 −26 mod/quiz/grade.php
  109. +167 −147 mod/quiz/index.php
  110. +34 −126 mod/quiz/lang/en/quiz.php
  111. +341 −471 mod/quiz/lib.php
  112. +640 −485 mod/quiz/locallib.php
  113. +254 −215 mod/quiz/mod_form.php
  114. +29 −5 mod/quiz/module.js
  115. +51 −33 mod/quiz/override_form.php
  116. +9 −9 mod/quiz/overridedelete.php
  117. +17 −17 mod/quiz/overrideedit.php
  118. +45 −32 mod/quiz/overrides.php
  119. BIN  mod/quiz/pix/icon.gif
  120. BIN  mod/quiz/pix/icon.png
  121. BIN  mod/quiz/pix/navflagged.png
  122. +66 −144 mod/quiz/processattempt.php
  123. +1,000 −0 mod/quiz/renderer.php
  124. +95 −90 mod/quiz/report.php
Sorry, we could not display the entire diff because too many files (576) changed.
View
2  admin/generator.php
@@ -622,7 +622,7 @@ public function generate_questions($courses, $modules) {
require_once($CFG->libdir .'/questionlib.php');
require_once($CFG->dirroot .'/mod/quiz/editlib.php');
$questions = array();
- $questionsmenu = question_type_menu();
+ $questionsmenu = question_bank::get_creatable_qtypes();
$questiontypes = array();
foreach ($questionsmenu as $qtype => $qname) {
$questiontypes[] = $qtype;
View
1  admin/index.php
@@ -355,7 +355,6 @@
}
// login user and let him set password and admin details
$adminuser->newadminuser = 1;
- message_set_default_message_preferences($adminuser);
complete_user_login($adminuser, false);
redirect("$CFG->wwwroot/user/editadvanced.php?id=$adminuser->id"); // Edit thyself
View
70 admin/message.php
@@ -0,0 +1,70 @@
+<?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/>.
+
+/**
+ * Message outputs configuration page
+ *
+ * @package message
+ * @copyright 2011 Lancaster University Network Services Limited
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+require_once(dirname(__FILE__) . '/../config.php');
+require_once($CFG->dirroot . '/message/lib.php');
+require_once($CFG->libdir.'/adminlib.php');
+
+// This is an admin page
+admin_externalpage_setup('managemessageoutputs');
+
+// Require site configuration capability
+require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+
+// Get the submitted params
+$disable = optional_param('disable', 0, PARAM_INT);
+$enable = optional_param('enable', 0, PARAM_INT);
+
+if (!empty($disable) && confirm_sesskey()) {
+ if (!$processor = $DB->get_record('message_processors', array('id'=>$disable))) {
+ print_error('outputdoesnotexist', 'message');
+ }
+ $DB->set_field('message_processors', 'enabled', '0', array('id'=>$processor->id)); // Disable output
+}
+
+if (!empty($enable) && confirm_sesskey() ) {
+ if (!$processor = $DB->get_record('message_processors', array('id'=>$enable))) {
+ print_error('outputdoesnotexist', 'message');
+ }
+ $DB->set_field('message_processors', 'enabled', '1', array('id'=>$processor->id)); // Enable output
+}
+
+if ($disable || $enable) {
+ $url = new moodle_url('message.php');
+ redirect($url);
+}
+// Page settings
+$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
+
+// Grab the renderer
+$renderer = $PAGE->get_renderer('core', 'message');
+
+// Display the manage message outputs interface
+$processors = get_message_processors();
+$messageoutputs = $renderer->manage_messageoutputs($processors);
+
+// Display the page
+echo $OUTPUT->header();
+echo $OUTPUT->heading(get_string('managemessageoutputs', 'message'));
+echo $messageoutputs;
+echo $OUTPUT->footer();
View
474 admin/qtypes.php
@@ -1,275 +1,297 @@
<?php
-// Allows the admin to manage question types.
-
- require_once(dirname(__FILE__) . '/../config.php');
- require_once($CFG->libdir . '/questionlib.php');
- require_once($CFG->libdir . '/adminlib.php');
- require_once($CFG->libdir . '/tablelib.php');
-
-/// Check permissions.
- require_login();
- $systemcontext = get_context_instance(CONTEXT_SYSTEM);
- require_capability('moodle/question:config', $systemcontext);
- $canviewreports = has_capability('report/questioninstances:view', $systemcontext);
-
- admin_externalpage_setup('manageqtypes');
-
-/// Get some data we will need - question counts and which types are needed.
- $counts = $DB->get_records_sql("
- SELECT qtype, COUNT(1) as numquestions, SUM(hidden) as numhidden
- FROM {question} GROUP BY qtype", array());
- $needed = array();
- foreach ($QTYPES as $qtypename => $qtype) {
- if (!isset($counts[$qtypename])) {
- $counts[$qtypename] = new stdClass;
- $counts[$qtypename]->numquestions = 0;
- $counts[$qtypename]->numhidden = 0;
- }
- $needed[$qtypename] = $counts[$qtypename]->numquestions > 0;
- $counts[$qtypename]->numquestions -= $counts[$qtypename]->numhidden;
- }
- $needed['missingtype'] = true; // The system needs the missing question type.
- foreach ($QTYPES as $qtypename => $qtype) {
- foreach ($qtype->requires_qtypes() as $reqtype) {
- $needed[$reqtype] = true;
- }
+
+// 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/>.
+
+/**
+ * Allows the admin to manage question types.
+ *
+ * @package moodlecore
+ * @subpackage questionbank
+ * @copyright 2008 Tim Hunt
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+require_once(dirname(__FILE__) . '/../config.php');
+require_once($CFG->libdir . '/questionlib.php');
+require_once($CFG->libdir . '/adminlib.php');
+require_once($CFG->libdir . '/tablelib.php');
+
+// Check permissions.
+require_login();
+$systemcontext = get_context_instance(CONTEXT_SYSTEM);
+require_capability('moodle/question:config', $systemcontext);
+$canviewreports = has_capability('report/questioninstances:view', $systemcontext);
+
+admin_externalpage_setup('manageqtypes');
+
+$qtypes = question_bank::get_all_qtypes();
+
+// Get some data we will need - question counts and which types are needed.
+$counts = $DB->get_records_sql("
+ SELECT qtype, COUNT(1) as numquestions, SUM(hidden) as numhidden
+ FROM {question} GROUP BY qtype", array());
+$needed = array();
+foreach ($qtypes as $qtypename => $qtype) {
+ if (!isset($counts[$qtypename])) {
+ $counts[$qtypename] = new stdClass;
+ $counts[$qtypename]->numquestions = 0;
+ $counts[$qtypename]->numhidden = 0;
}
- foreach ($counts as $qtypename => $count) {
- if (!isset($QTYPES[$qtypename])) {
- $counts['missingtype']->numquestions += $count->numquestions - $count->numhidden;
- $counts['missingtype']->numhidden += $count->numhidden;
- }
+ $needed[$qtypename] = $counts[$qtypename]->numquestions > 0;
+ $counts[$qtypename]->numquestions -= $counts[$qtypename]->numhidden;
+}
+$needed['missingtype'] = true; // The system needs the missing question type.
+foreach ($qtypes as $qtypename => $qtype) {
+ foreach ($qtype->requires_qtypes() as $reqtype) {
+ $needed[$reqtype] = true;
}
-
-/// Work of the correct sort order.
- $config = get_config('question');
- $sortedqtypes = array();
- foreach ($QTYPES as $qtypename => $qtype) {
- $sortedqtypes[$qtypename] = $qtype->local_name();
+}
+foreach ($counts as $qtypename => $count) {
+ if (!isset($qtypes[$qtypename])) {
+ $counts['missingtype']->numquestions += $count->numquestions - $count->numhidden;
+ $counts['missingtype']->numhidden += $count->numhidden;
}
- $sortedqtypes = question_sort_qtype_array($sortedqtypes, $config);
+}
-/// Process actions ============================================================
+// Work of the correct sort order.
+$config = get_config('question');
+$sortedqtypes = array();
+foreach ($qtypes as $qtypename => $qtype) {
+ $sortedqtypes[$qtypename] = $qtype->local_name();
+}
+$sortedqtypes = question_bank::sort_qtype_array($sortedqtypes, $config);
- // Disable.
- if (($disable = optional_param('disable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
- if (!isset($QTYPES[$disable])) {
- print_error('unknownquestiontype', 'question', admin_url('qtypes.php'), $disable);
- }
+// Process actions ============================================================
- set_config($disable . '_disabled', 1, 'question');
- redirect(admin_url('qtypes.php'));
+// Disable.
+if (($disable = optional_param('disable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
+ if (!isset($qtypes[$disable])) {
+ print_error('unknownquestiontype', 'question', new moodle_url('/admin/qtypes.php'), $disable);
}
- // Enable.
- if (($enable = optional_param('enable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
- if (!isset($QTYPES[$enable])) {
- print_error('unknownquestiontype', 'question', admin_url('qtypes.php'), $enable);
- }
+ set_config($disable . '_disabled', 1, 'question');
+ redirect(admin_url('qtypes.php'));
+}
- if (!$QTYPES[$enable]->menu_name()) {
- print_error('cannotenable', 'question', admin_url('qtypes.php'), $enable);
- }
+// Enable.
+if (($enable = optional_param('enable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
+ if (!isset($qtypes[$enable])) {
+ print_error('unknownquestiontype', 'question', new moodle_url('/admin/qtypes.php'), $enable);
+ }
- unset_config($enable . '_disabled', 'question');
- redirect(admin_url('qtypes.php'));
+ if (!$qtypes[$enable]->menu_name()) {
+ print_error('cannotenable', 'question', new moodle_url('/admin/qtypes.php'), $enable);
}
- // Move up in order.
- if (($up = optional_param('up', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
- if (!isset($QTYPES[$up])) {
- print_error('unknownquestiontype', 'question', admin_url('qtypes.php'), $up);
- }
+ unset_config($enable . '_disabled', 'question');
+ redirect(new moodle_url('/admin/qtypes.php'));
+}
- $neworder = question_reorder_qtypes($sortedqtypes, $up, -1);
- question_save_qtype_order($neworder, $config);
- redirect(admin_url('qtypes.php'));
+// Move up in order.
+if (($up = optional_param('up', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
+ if (!isset($qtypes[$up])) {
+ print_error('unknownquestiontype', 'question', new moodle_url('/admin/qtypes.php'), $up);
}
- // Move down in order.
- if (($down = optional_param('down', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
- if (!isset($QTYPES[$down])) {
- print_error('unknownquestiontype', 'question', admin_url('qtypes.php'), $down);
- }
+ $neworder = question_reorder_qtypes($sortedqtypes, $up, -1);
+ question_save_qtype_order($neworder, $config);
+ redirect(new moodle_url('/admin/qtypes.php'));
+}
- $neworder = question_reorder_qtypes($sortedqtypes, $down, +1);
- question_save_qtype_order($neworder, $config);
- redirect(admin_url('qtypes.php'));
+// Move down in order.
+if (($down = optional_param('down', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
+ if (!isset($qtypes[$down])) {
+ print_error('unknownquestiontype', 'question', admin_url('qtypes.php'), $down);
}
- // Delete.
- if (($delete = optional_param('delete', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
- // Check it is OK to delete this question type.
- if ($delete == 'missingtype') {
- print_error('cannotdeletemissingqtype', 'admin', admin_url('qtypes.php'));
- }
+ $neworder = question_reorder_qtypes($sortedqtypes, $down, +1);
+ question_save_qtype_order($neworder, $config);
+ redirect(new moodle_url('/admin/qtypes.php'));
+}
- if (!isset($QTYPES[$delete])) {
- print_error('unknownquestiontype', 'question', admin_url('qtypes.php'), $delete);
- }
+// Delete.
+if (($delete = optional_param('delete', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
+ // Check it is OK to delete this question type.
+ if ($delete == 'missingtype') {
+ print_error('cannotdeletemissingqtype', 'admin', new moodle_url('/admin/qtypes.php'));
+ }
- $qtypename = $QTYPES[$delete]->local_name();
- if ($counts[$delete]->numquestions + $counts[$delete]->numhidden > 0) {
- print_error('cannotdeleteqtypeinuse', 'admin', admin_url('qtypes.php'), $qtypename);
- }
+ if (!isset($qtypes[$delete])) {
+ print_error('unknownquestiontype', 'question', new moodle_url('/admin/qtypes.php'), $delete);
+ }
- if ($needed[$delete] > 0) {
- print_error('cannotdeleteqtypeneeded', 'admin', admin_url('qtypes.php'), $qtypename);
- }
+ $qtypename = $qtypes[$delete]->local_name();
+ if ($counts[$delete]->numquestions + $counts[$delete]->numhidden > 0) {
+ print_error('cannotdeleteqtypeinuse', 'admin', new moodle_url('/admin/qtypes.php'), $qtypename);
+ }
- // If not yet confirmed, display a confirmation message.
- if (!optional_param('confirm', '', PARAM_BOOL)) {
- $qtypename = $QTYPES[$delete]->local_name();
- echo $OUTPUT->header();
- echo $OUTPUT->heading(get_string('deleteqtypeareyousure', 'admin', $qtypename));
- echo $OUTPUT->confirm(get_string('deleteqtypeareyousuremessage', 'admin', $qtypename),
- admin_url('qtypes.php?delete=' . $delete . '&confirm=1'),
- admin_url('qtypes.php'));
- echo $OUTPUT->footer();
- exit;
- }
+ if ($needed[$delete] > 0) {
+ print_error('cannotdeleteqtypeneeded', 'admin', new moodle_url('/admin/qtypes.php'), $qtypename);
+ }
- // Do the deletion.
+ // If not yet confirmed, display a confirmation message.
+ if (!optional_param('confirm', '', PARAM_BOOL)) {
+ $qtypename = $qtypes[$delete]->local_name();
echo $OUTPUT->header();
- echo $OUTPUT->heading(get_string('deletingqtype', 'admin', $qtypename));
-
- // Delete any configuration records.
- if (!unset_all_config_for_plugin('qtype_' . $delete)) {
- echo $OUTPUT->notification(get_string('errordeletingconfig', 'admin', 'qtype_' . $delete));
- }
- unset_config($delete . '_disabled', 'question');
- unset_config($delete . '_sortorder', 'question');
-
- // Then the tables themselves
- drop_plugin_tables($delete, $QTYPES[$delete]->plugin_dir() . '/db/install.xml', false);
-
- // Remove event handlers and dequeue pending events
- events_uninstall('qtype/' . $delete);
-
- $a->qtype = $qtypename;
- $a->directory = $QTYPES[$delete]->plugin_dir();
- echo $OUTPUT->box(get_string('qtypedeletefiles', 'admin', $a), 'generalbox', 'notice');
- echo $OUTPUT->continue_button(admin_url('qtypes.php'));
+ echo $OUTPUT->heading(get_string('deleteqtypeareyousure', 'admin', $qtypename));
+ echo $OUTPUT->confirm(get_string('deleteqtypeareyousuremessage', 'admin', $qtypename),
+ new moodle_url('/admin/qtypes.php', array('delete' => $delete, 'confirm' => 1)),
+ new moodle_url('/admin/qtypes.php'));
echo $OUTPUT->footer();
exit;
}
- // End of process actions ==================================================
-
-/// Print the page heading.
+ // Do the deletion.
echo $OUTPUT->header();
- echo $OUTPUT->heading(get_string('manageqtypes', 'admin'));
-
-/// Set up the table.
- $table = new flexible_table('qtypeadmintable');
- $table->define_columns(array('questiontype', 'numquestions', 'version', 'requires',
- 'availableto', 'delete', 'settings'));
- $table->define_headers(array(get_string('questiontype', 'admin'), get_string('numquestions', 'admin'),
- get_string('version'), get_string('requires', 'admin'), get_string('availableq', 'question'),
- get_string('delete'), get_string('settings')));
- $table->set_attribute('id', 'qtypes');
- $table->set_attribute('class', 'generaltable generalbox boxaligncenter boxwidthwide');
- $table->setup();
-
-/// Add a row for each question type.
- $createabletypes = question_type_menu();
- foreach ($sortedqtypes as $qtypename => $localname) {
- $qtype = $QTYPES[$qtypename];
- $row = array();
-
- // Question icon and name.
- $fakequestion = new stdClass;
- $fakequestion->qtype = $qtypename;
- $icon = print_question_icon($fakequestion, true);
- $row[] = $icon . ' ' . $localname;
-
- // Number of questions of this type.
- if ($counts[$qtypename]->numquestions + $counts[$qtypename]->numhidden > 0) {
- if ($counts[$qtypename]->numhidden > 0) {
- $strcount = get_string('numquestionsandhidden', 'admin', $counts[$qtypename]);
- } else {
- $strcount = $counts[$qtypename]->numquestions;
- }
- if ($canviewreports) {
- $row[] = '<a href="' . admin_url('/report/questioninstances/index.php?qtype=' . $qtypename) .
- '" title="' . get_string('showdetails', 'admin') . '">' . $strcount . '</a>';
- } else {
- $strcount;
- }
- } else {
- $row[] = 0;
- }
+ echo $OUTPUT->heading(get_string('deletingqtype', 'admin', $qtypename));
- // Question version number.
- $version = get_config('qtype_' . $qtypename, 'version');
- if ($version) {
- $row[] = $version;
- } else {
- $row[] = '<span class="disabled">' . get_string('nodatabase', 'admin') . '</span>';
- }
+ // Delete any configuration records.
+ if (!unset_all_config_for_plugin('qtype_' . $delete)) {
+ echo $OUTPUT->notification(get_string('errordeletingconfig', 'admin', 'qtype_' . $delete));
+ }
+ unset_config($delete . '_disabled', 'question');
+ unset_config($delete . '_sortorder', 'question');
- // Other question types required by this one.
- $requiredtypes = $qtype->requires_qtypes();
- $strtypes = array();
- if (!empty($requiredtypes)) {
- foreach ($requiredtypes as $required) {
- $strtypes[] = $QTYPES[$required]->local_name();
- }
- $row[] = implode(', ', $strtypes);
+ // Then the tables themselves
+ drop_plugin_tables($delete, $qtypes[$delete]->plugin_dir() . '/db/install.xml', false);
+
+ // Remove event handlers and dequeue pending events
+ events_uninstall('qtype/' . $delete);
+
+ $a->qtype = $qtypename;
+ $a->directory = $qtypes[$delete]->plugin_dir();
+ echo $OUTPUT->box(get_string('qtypedeletefiles', 'admin', $a), 'generalbox', 'notice');
+ echo $OUTPUT->continue_button(new moodle_url('/admin/qtypes.php'));
+ echo $OUTPUT->footer();
+ exit;
+}
+
+// End of process actions ==================================================
+
+// Print the page heading.
+echo $OUTPUT->header();
+echo $OUTPUT->heading(get_string('manageqtypes', 'admin'));
+
+// Set up the table.
+$table = new flexible_table('qtypeadmintable');
+$table->define_baseurl(new moodle_url('/admin/qtypes.php'));
+$table->define_columns(array('questiontype', 'numquestions', 'version', 'requires',
+ 'availableto', 'delete', 'settings'));
+$table->define_headers(array(get_string('questiontype', 'admin'), get_string('numquestions', 'admin'),
+ get_string('version'), get_string('requires', 'admin'), get_string('availableq', 'question'),
+ get_string('delete'), get_string('settings')));
+$table->set_attribute('id', 'qtypes');
+$table->set_attribute('class', 'generaltable generalbox boxaligncenter boxwidthwide');
+$table->setup();
+
+// Add a row for each question type.
+$createabletypes = question_bank::get_creatable_qtypes();
+foreach ($sortedqtypes as $qtypename => $localname) {
+ $qtype = $qtypes[$qtypename];
+ $row = array();
+
+ // Question icon and name.
+ $fakequestion = new stdClass;
+ $fakequestion->qtype = $qtypename;
+ $icon = print_question_icon($fakequestion, true);
+ $row[] = $icon . ' ' . $localname;
+
+ // Number of questions of this type.
+ if ($counts[$qtypename]->numquestions + $counts[$qtypename]->numhidden > 0) {
+ if ($counts[$qtypename]->numhidden > 0) {
+ $strcount = get_string('numquestionsandhidden', 'admin', $counts[$qtypename]);
} else {
- $row[] = '';
+ $strcount = $counts[$qtypename]->numquestions;
}
-
- // Are people allowed to create new questions of this type?
- $rowclass = '';
- if ($qtype->menu_name()) {
- $createable = isset($createabletypes[$qtypename]);
- $icons = enable_disable_button($qtypename, $createable);
- if (!$createable) {
- $rowclass = 'dimmed_text';
- }
+ if ($canviewreports) {
+ $row[] = '<a href="' . new moodle_url('/admin/report/questioninstances/index.php', array('qtype' => $qtypename)) .
+ '" title="' . get_string('showdetails', 'admin') . '">' . $strcount . '</a>';
} else {
- $icons = '<img src="' . $OUTPUT->pix_url('spacer') . '" alt="" class="spacer" />';
+ $strcount;
}
+ } else {
+ $row[] = 0;
+ }
- // Move icons.
- $icons .= icon_html('up', $qtypename, 't/up', get_string('up'), '');
- $icons .= icon_html('down', $qtypename, 't/down', get_string('down'), '');
- $row[] = $icons;
+ // Question version number.
+ $version = get_config('qtype_' . $qtypename, 'version');
+ if ($version) {
+ $row[] = $version;
+ } else {
+ $row[] = '<span class="disabled">' . get_string('nodatabase', 'admin') . '</span>';
+ }
- // Delete link, if available.
- if ($needed[$qtypename]) {
- $row[] = '';
- } else {
- $row[] = '<a href="' . admin_url('qtypes.php?delete=' . $qtypename .
- '&amp;sesskey=' . sesskey()) . '" title="' .
- get_string('uninstallqtype', 'admin') . '">' . get_string('delete') . '</a>';
+ // Other question types required by this one.
+ $requiredtypes = $qtype->requires_qtypes();
+ $strtypes = array();
+ if (!empty($requiredtypes)) {
+ foreach ($requiredtypes as $required) {
+ $strtypes[] = $qtypes[$required]->local_name();
}
+ $row[] = implode(', ', $strtypes);
+ } else {
+ $row[] = '';
+ }
- // Settings link, if available.
- $settings = admin_get_root()->locate('qtypesetting' . $qtypename);
- if ($settings instanceof admin_externalpage) {
- $row[] = '<a href="' . $settings->url .
- '">' . get_string('settings') . '</a>';
- } else if ($settings instanceof admin_settingpage) {
- $row[] = '<a href="' . admin_url('settings.php?section=qtypesetting' . $qtypename) .
- '">' . get_string('settings') . '</a>';
- } else {
- $row[] = '';
+ // Are people allowed to create new questions of this type?
+ $rowclass = '';
+ if ($qtype->menu_name()) {
+ $createable = isset($createabletypes[$qtypename]);
+ $icons = enable_disable_button($qtypename, $createable);
+ if (!$createable) {
+ $rowclass = 'dimmed_text';
}
-
- $table->add_data($row, $rowclass);
+ } else {
+ $icons = '<img src="' . $OUTPUT->pix_url('spacer') . '" alt="" class="spacer" />';
}
- $table->finish_output();
+ // Move icons.
+ $icons .= icon_html('up', $qtypename, 't/up', get_string('up'), '');
+ $icons .= icon_html('down', $qtypename, 't/down', get_string('down'), '');
+ $row[] = $icons;
- echo $OUTPUT->footer();
+ // Delete link, if available.
+ if ($needed[$qtypename]) {
+ $row[] = '';
+ } else {
+ $row[] = '<a href="' . new moodle_url('/admin/qtypes.php', array('delete' => $qtypename,
+ 'sesskey' => sesskey())) . '" title="' .
+ get_string('uninstallqtype', 'admin') . '">' . get_string('delete') . '</a>';
+ }
+
+ // Settings link, if available.
+ $settings = admin_get_root()->locate('qtypesetting' . $qtypename);
+ if ($settings instanceof admin_externalpage) {
+ $row[] = '<a href="' . $settings->url .
+ '">' . get_string('settings') . '</a>';
+ } else if ($settings instanceof admin_settingpage) {
+ $row[] = '<a href="' . new moodle_url('/admin/settings.php', array('section' => 'qtypesetting' . $qtypename)) .
+ '">' . get_string('settings') . '</a>';
+ } else {
+ $row[] = '';
+ }
-function admin_url($endbit) {
- global $CFG;
- return $CFG->wwwroot . '/' . $CFG->admin . '/' . $endbit;
+ $table->add_data($row, $rowclass);
}
+$table->finish_output();
+
+echo $OUTPUT->footer();
+
function enable_disable_button($qtypename, $createable) {
if ($createable) {
return icon_html('disable', $qtypename, 'i/hide', get_string('enabled', 'question'), get_string('disable'));
@@ -283,7 +305,7 @@ function icon_html($action, $qtypename, $icon, $alt, $tip) {
if ($tip) {
$tip = 'title="' . $tip . '" ';
}
- $html = ' <form action="' . admin_url('qtypes.php') . '" method="post"><div>';
+ $html = ' <form action="' . new moodle_url('/admin/qtypes.php') . '" method="post"><div>';
$html .= '<input type="hidden" name="sesskey" value="' . sesskey() . '" />';
$html .= '<input type="image" name="' . $action . '" value="' . $qtypename .
'" src="' . $OUTPUT->pix_url($icon) . '" alt="' . $alt . '" ' . $tip . '/>';
View
4 admin/registration/confirmregistration.php
@@ -47,7 +47,7 @@
admin_externalpage_setup('registrationindex');
if (!empty($error) and $error == 'urlalreadyexist') {
- throw new moodle_exception('urlalreadyregistered', 'hub',
+ throw new moodle_exception('urlalreadyregistered', 'hub',
$CFG->wwwroot . '/' . $CFG->admin . '/registration/index.php');
}
@@ -85,7 +85,7 @@
echo $OUTPUT->footer();
} else {
- throw new moodle_exception('wrongtoken', 'hub',
+ throw new moodle_exception('wrongtoken', 'hub',
$CFG->wwwroot . '/' . $CFG->admin . '/registration/index.php');
}
View
4 admin/registration/index.php
@@ -148,12 +148,12 @@
$moodleorghub = $registrationmanager->get_registeredhub(HUB_MOODLEORGHUBURL);
if (!empty($moodleorghub)) {
$registeredonmoodleorg = true;
- }
+ }
echo $OUTPUT->heading(get_string('registeron', 'hub'), 3, 'main');
echo $renderer->registrationselector($registeredonmoodleorg);
- if (extension_loaded('xmlrpc')) {
+ if (extension_loaded('xmlrpc')) {
$hubs = $registrationmanager->get_registered_on_hubs();
if (!empty($hubs)) {
echo $OUTPUT->heading(get_string('registeredon', 'hub'), 3, 'main');
View
8 admin/report/questioninstances/index.php
@@ -22,8 +22,9 @@
add_to_log(SITEID, "admin", "report questioninstances", "report/questioninstances/index.php?qtype=$requestedqtype", $requestedqtype);
// Prepare the list of capabilities to choose from
+$qtypes = question_bank::get_all_qtypes();
$qtypechoices = array();
-foreach ($QTYPES as $qtype) {
+foreach ($qtypes as $qtype) {
$qtypechoices[$qtype->name()] = $qtype->local_name();
}
@@ -45,7 +46,7 @@
// Work out the bits needed for the SQL WHERE clauses.
if ($requestedqtype == 'missingtype') {
- $othertypes = array_keys($QTYPES);
+ $othertypes = array_keys($qtypes);
$key = array_search('missingtype', $othertypes);
unset($othertypes[$key]);
list($sqlqtypetest, $params) = $DB->get_in_or_equal($othertypes, SQL_PARAMS_QM, '', false);
@@ -58,7 +59,8 @@
} else {
$sqlqtypetest = 'WHERE qtype = ?';
$params = array($requestedqtype);
- $title = get_string('reportforqtype', 'report_questioninstances', $QTYPES[$requestedqtype]->local_name());
+ $title = get_string('reportforqtype', 'report_questioninstances',
+ question_bank::get_qtype($requestedqtype)->local_name());
}
// Get the question counts, and all the context information, for each
View
2  admin/report/spamcleaner/module.js
@@ -108,7 +108,7 @@ M.report_spamcleaner = {
context.Y = Y;
context.me = me;
if (Y.one("#removeall_btn")) {
- Y.on("click", context.del_all, "#removeall_btn");
+ Y.on("click", context.del_all, "#removeall_btn");
}
});
}
View
2  admin/roles/module.js
@@ -138,7 +138,7 @@ M.core_role.init_cap_table_filter = function(Y, tableid, contextid) {
lastheading = null;
this.setFilterCookieValue(filtertext);
-
+
this.button.set('disabled', (filtertext == ''));
this.table.all('tr').each(function(row){
View
2  admin/settings/appearance.php
@@ -18,6 +18,8 @@
$temp->add(new admin_setting_configcheckbox('allowuserblockhiding', get_string('allowuserblockhiding', 'admin'), get_string('configallowuserblockhiding', 'admin'), 1));
$temp->add(new admin_setting_configcheckbox('allowblockstodock', get_string('allowblockstodock', 'admin'), get_string('configallowblockstodock', 'admin'), 1));
$temp->add(new admin_setting_configtextarea('custommenuitems', get_string('custommenuitems', 'admin'), get_string('configcustommenuitems', 'admin'), '', PARAM_TEXT, '50', '10'));
+ $temp->add(new admin_setting_configcheckbox('enabledevicedetection', get_string('enabledevicedetection', 'admin'), get_string('configenabledevicedetection', 'admin'), 1));
+ $temp->add(new admin_setting_devicedetectregex('devicedetectregex', get_string('devicedetectregex', 'admin'), get_string('devicedetectregex_desc', 'admin'), ''));
$ADMIN->add('themes', $temp);
$ADMIN->add('themes', new admin_externalpage('themeselector', get_string('themeselector','admin'), $CFG->wwwroot . '/theme/index.php'));
View
6 admin/settings/courses.php
@@ -139,7 +139,7 @@
400 => '400',
500 => '500');
$temp->add(new admin_setting_configselect('backup/backup_auto_keep', get_string('keep'), get_string('backupkeephelp'), 1, $keepoptoins));
-
+
$temp->add(new admin_setting_heading('automatedsettings', get_string('automatedsettings','backup'), ''));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_users', get_string('users'), get_string('backupusershelp'), 1));
@@ -152,8 +152,8 @@
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_userscompletion', get_string('generaluserscompletion','backup'), get_string('configgeneraluserscompletion','backup'), 1));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_logs', get_string('logs'), get_string('backuplogshelp'), 0));
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_histories', get_string('generalhistories','backup'), get_string('configgeneralhistories','backup'), 0));
-
-
+
+
//$temp->add(new admin_setting_configcheckbox('backup/backup_auto_messages', get_string('messages', 'message'), get_string('backupmessageshelp','message'), 0));
//$temp->add(new admin_setting_configcheckbox('backup/backup_auto_blogs', get_string('blogs', 'blog'), get_string('backupblogshelp','blog'), 0));
View
24 admin/settings/plugins.php
@@ -46,6 +46,27 @@
}
}
+ // message outputs
+ $ADMIN->add('modules', new admin_category('messageoutputs', get_string('messageoutputs', 'message')));
+ $ADMIN->add('messageoutputs', new admin_page_managemessageoutputs());
+ $ADMIN->add('messageoutputs', new admin_page_defaultmessageoutputs());
+ require_once($CFG->dirroot.'/message/lib.php');
+ $processors = get_message_processors();
+ foreach ($processors as $processor) {
+ $processorname = $processor->name;
+ if (!$processor->available) {
+ continue;
+ }
+ if ($processor->hassettings) {
+ $strprocessorname = get_string('pluginname', 'message_'.$processorname);
+ $settings = new admin_settingpage('messagesetting'.$processorname, $strprocessorname, 'moodle/site:config', !$processor->enabled);
+ include($CFG->dirroot.'/message/output/'.$processor->name.'/settings.php');
+ if ($settings) {
+ $ADMIN->add('messageoutputs', $settings);
+ }
+ }
+ }
+
// authentication plugins
$ADMIN->add('modules', new admin_category('authsettings', get_string('authentication', 'admin')));
@@ -324,6 +345,9 @@
$ADMIN->add('webservicesettings', $temp);
/// manage service
$temp = new admin_settingpage('externalservices', get_string('externalservices', 'webservice'));
+ $enablemobiledocurl = new moodle_url(get_docs_url('Enable_mobile_web_services'));
+ $enablemobiledoclink = html_writer::link($enablemobiledocurl, get_string('documentation'));
+ $temp->add(new admin_setting_enablemobileservice('enablemobilewebservice', get_string('enablemobilewebservice', 'admin'), get_string('configenablemobilewebservice', 'admin', $enablemobiledoclink), 0));
$temp->add(new admin_setting_heading('manageserviceshelpexplaination', get_string('information', 'webservice'), get_string('servicehelpexplanation', 'webservice')));
$temp->add(new admin_setting_manageexternalservices());
$ADMIN->add('webservicesettings', $temp);
View
53 admin/settings/server.php
@@ -17,46 +17,8 @@
-// "email" settingpage
-$temp = new admin_settingpage('mail', get_string('mail','admin'));
-$temp->add(new admin_setting_configtext('smtphosts', get_string('smtphosts', 'admin'), get_string('configsmtphosts', 'admin'), '', PARAM_RAW));
-$temp->add(new admin_setting_configtext('smtpuser', get_string('smtpuser', 'admin'), get_string('configsmtpuser', 'admin'), '', PARAM_NOTAGS));
-$temp->add(new admin_setting_configpasswordunmask('smtppass', get_string('smtppass', 'admin'), get_string('configsmtpuser', 'admin'), ''));
-$temp->add(new admin_setting_configtext('smtpmaxbulk', get_string('smtpmaxbulk', 'admin'), get_string('configsmtpmaxbulk', 'admin'), 1, PARAM_INT));
-$temp->add(new admin_setting_configtext('noreplyaddress', get_string('noreplyaddress', 'admin'), get_string('confignoreplyaddress', 'admin'), 'noreply@' . get_host_from_url($CFG->wwwroot), PARAM_NOTAGS));
-$temp->add(new admin_setting_configselect('digestmailtime', get_string('digestmailtime', 'admin'), get_string('configdigestmailtime', 'admin'), 17, array('00' => '00',
- '01' => '01',
- '02' => '02',
- '03' => '03',
- '04' => '04',
- '05' => '05',
- '06' => '06',
- '07' => '07',
- '08' => '08',
- '09' => '09',
- '10' => '10',
- '11' => '11',
- '12' => '12',
- '13' => '13',
- '14' => '14',
- '15' => '15',
- '16' => '16',
- '17' => '17',
- '18' => '18',
- '19' => '19',
- '20' => '20',
- '21' => '21',
- '22' => '22',
- '23' => '23')));
-$charsets = get_list_of_charsets();
-unset($charsets['UTF-8']); // not needed here
-$options = array();
-$options['0'] = 'UTF-8';
-$options = array_merge($options, $charsets);
-$temp->add(new admin_setting_configselect('sitemailcharset', get_string('sitemailcharset', 'admin'), get_string('configsitemailcharset','admin'), '0', $options));
-$temp->add(new admin_setting_configcheckbox('allowusermailcharset', get_string('allowusermailcharset', 'admin'), get_string('configallowusermailcharset', 'admin'), 0));
-$options = array('LF'=>'LF', 'CRLF'=>'CRLF');
-$temp->add(new admin_setting_configselect('mailnewline', get_string('mailnewline', 'admin'), get_string('configmailnewline','admin'), 'LF', $options));
+// "supportcontact" settingpage
+$temp = new admin_settingpage('supportcontact', get_string('supportcontact','admin'));
if (isloggedin()) {
global $USER;
$primaryadminemail = $USER->email;
@@ -73,17 +35,6 @@
$ADMIN->add('server', $temp);
-// Jabber settingpage
-$temp = new admin_settingpage('jabber', get_string('jabber', 'admin'));
-$temp->add(new admin_setting_configtext('jabberhost', get_string('jabberhost', 'admin'), get_string('configjabberhost', 'admin'), '', PARAM_RAW));
-$temp->add(new admin_setting_configtext('jabberserver', get_string('jabberserver', 'admin'), get_string('configjabberserver', 'admin'), '', PARAM_RAW));
-$temp->add(new admin_setting_configtext('jabberusername', get_string('jabberusername', 'admin'), get_string('configjabberusername', 'admin'), '', PARAM_RAW));
-$temp->add(new admin_setting_configpasswordunmask('jabberpassword', get_string('jabberpassword', 'admin'), get_string('configjabberpassword', 'admin'), ''));
-$temp->add(new admin_setting_configtext('jabberport', get_string('jabberport', 'admin'), get_string('configjabberport', 'admin'), 5222, PARAM_INT));
-$ADMIN->add('server', $temp);
-
-
-
// "sessionhandling" settingpage
$temp = new admin_settingpage('sessionhandling', get_string('sessionhandling', 'admin'));
$temp->add(new admin_setting_configcheckbox('dbsessions', get_string('dbsessions', 'admin'), get_string('configdbsessions', 'admin'), 1));
View
4 admin/webservice/service_user_settings.php
@@ -33,7 +33,7 @@
admin_externalpage_setup('externalserviceusersettings');
//define nav bar
-$PAGE->set_url('/' . $CFG->admin . '/webservice/service_user_settings.php',
+$PAGE->set_url('/' . $CFG->admin . '/webservice/service_user_settings.php',
array('id' => $serviceid, 'userid' => $userid));
$node = $PAGE->settingsnav->find('externalservices', navigation_node::TYPE_SETTING);
if ($node) {
@@ -62,7 +62,7 @@
$serviceuserinfo->id = $serviceuser->serviceuserid;
$serviceuserinfo->iprestriction = $settingsformdata->iprestriction;
$serviceuserinfo->validuntil = $settingsformdata->validuntil;
-
+
$webservicemanager->update_ws_authorised_user($serviceuserinfo);
//TODO: assign capability
View
4 admin/webservice/testclient.php
@@ -37,7 +37,7 @@
$PAGE->navbar->ignore_active(true);
$PAGE->navbar->add(get_string('administrationsite'));
$PAGE->navbar->add(get_string('development', 'admin'));
-$PAGE->navbar->add(get_string('testclient', 'webservice'),
+$PAGE->navbar->add(get_string('testclient', 'webservice'),
new moodle_url('/' . $CFG->admin . '/webservice/testclient.php'));
if (!empty($function)) {
$PAGE->navbar->add($function);
@@ -169,4 +169,4 @@
$mform->display();
echo $OUTPUT->footer();
die;
-}
+}
View
2  admin/webservice/tokens.php
@@ -94,7 +94,7 @@
die;
break;
- case 'delete':
+ case 'delete':
$token = $webservicemanager->get_created_by_user_ws_token($USER->id, $tokenid);
//Delete the token
View
3  backup/moodle2/backup_qtype_plugin.class.php
@@ -111,8 +111,7 @@ protected function add_question_numerical_options($element) {
// Define the elements
$options = new backup_nested_element('numerical_options');
$option = new backup_nested_element('numerical_option', array('id'), array(
- 'instructions', 'instructionsformat', 'showunits', 'unitsleft',
- 'unitgradingtype', 'unitpenalty'));
+ 'showunits', 'unitsleft', 'unitgradingtype', 'unitpenalty'));
// Build the tree
$element->add_child($options);
View
117 backup/moodle2/backup_stepslib.php
@@ -174,78 +174,76 @@ protected function prepare_activity_structure($activitystructure) {
/**
* Attach to $element (usually attempts) the needed backup structures
- * for question_states for a given question_attempt
+ * for question_usages and all the associated data.
*/
- protected function add_question_attempts_states($element, $questionattemptname) {
+ protected function add_question_usages($element, $usageidname) {
+ global $CFG;
+ require_once($CFG->dirroot . '/question/engine/lib.php');
+
// Check $element is one nested_backup_element
if (! $element instanceof backup_nested_element) {
throw new backup_step_exception('question_states_bad_parent_element', $element);
}
- // Check that the $questionattemptname is final element in $element
- if (! $element->get_final_element($questionattemptname)) {
- throw new backup_step_exception('question_states_bad_question_attempt_element', $questionattemptname);
+ if (! $element->get_final_element($usageidname)) {
+ throw new backup_step_exception('question_states_bad_question_attempt_element', $usageidname);
}
- // TODO: Some day we should stop these "encrypted" state->answers and
- // TODO: delegate to qtypes plugin to proper XML writting the needed info on each question
-
- // TODO: Should be doing here some introspection in the "answer" element, based on qtype,
- // TODO: to know which real questions are being used (for randoms and other qtypes...)
- // TODO: Not needed if consistency is guaranteed, but it isn't right now :-(
+ $quba = new backup_nested_element('question_usage', array('id'),
+ array('component', 'preferredbehaviour'));
- // Define the elements
- $states = new backup_nested_element('states');
- $state = new backup_nested_element('state', array('id'), array(
- 'question', 'seq_number', 'answer', 'timestamp',
- 'event', 'grade', 'raw_grade', 'penalty'));
+ $qas = new backup_nested_element('question_attempts');
+ $qa = new backup_nested_element('question_attempt', array('id'), array(
+ 'slot', 'behaviour', 'questionid', 'maxmark', 'minfraction',
+ 'flagged', 'questionsummary', 'rightanswer', 'responsesummary',
+ 'timemodified'));
- // Build the tree
- $element->add_child($states);
- $states->add_child($state);
-
- // Set the sources
- $state->set_source_table('question_states', array('attempt' => '../../' . $questionattemptname));
+ $steps = new backup_nested_element('steps');
+ $step = new backup_nested_element('step', array('id'), array(
+ 'sequencenumber', 'state', 'fraction', 'timecreated', 'userid'));
- // Annotate ids
- $state->annotate_ids('question', 'question');
- }
-
- /**
- * Attach to $element (usually attempts) the needed backup structures
- * for question_sessions for a given question_attempt
- */
- protected function add_question_attempts_sessions($element, $questionattemptname) {
- // Check $element is one nested_backup_element
- if (! $element instanceof backup_nested_element) {
- throw new backup_step_exception('question_sessions_bad_parent_element', $element);
- }
- // Check that the $questionattemptname is final element in $element
- if (! $element->get_final_element($questionattemptname)) {
- throw new backup_step_exception('question_sessions_bad_question_attempt_element', $questionattemptname);
- }
-
- // Define the elements
- $sessions = new backup_nested_element('sessions');
- $session = new backup_nested_element('session', array('id'), array(
- 'questionid', 'newest', 'newgraded', 'sumpenalty',
- 'manualcomment', 'manualcommentformat', 'flagged'));
+ $response = new backup_nested_element('response');
+ $variable = new backup_nested_element('variable', null, array('name', 'value'));
// Build the tree
- $element->add_child($sessions);
- $sessions->add_child($session);
+ $element->add_child($quba);
+ $quba->add_child($qas);
+ $qas->add_child($qa);
+ $qa->add_child($steps);
+ $steps->add_child($step);
+ $step->add_child($response);
+ $response->add_child($variable);
// Set the sources
- $session->set_source_table('question_sessions', array('attemptid' => '../../' . $questionattemptname));
+ $quba->set_source_table('question_usages',
+ array('id' => '../' . $usageidname));
+ $qa->set_source_sql('
+ SELECT *
+ FROM {question_attempts}
+ WHERE questionusageid = :questionusageid
+ ORDER BY slot',
+ array('questionusageid' => backup::VAR_PARENTID));
+ $step->set_source_sql('
+ SELECT *
+ FROM {question_attempt_steps}
+ WHERE questionattemptid = :questionattemptid
+ ORDER BY sequencenumber',
+ array('questionattemptid' => backup::VAR_PARENTID));
+ $variable->set_source_table('question_attempt_step_data',
+ array('attemptstepid' => backup::VAR_PARENTID));
// Annotate ids
- $session->annotate_ids('question', 'questionid');
+ $qa->annotate_ids('question', 'questionid');
+ $step->annotate_ids('user', 'userid');
// Annotate files
- // Note: question_sessions haven't files associated. On purpose manualcomment is lacking
- // support for them, so we don't need to annotated them here.
+ $fileareas = question_engine::get_all_response_file_areas();
+ foreach ($fileareas as $filearea) {
+ $step->annotate_files('question', $filearea, 'id');
+ }
}
}
+
/**
* backup structure step in charge of calculating the categories to be
* included in backup, based in the context being backuped (module/course)
@@ -1670,19 +1668,25 @@ protected function define_structure() {
$question = new backup_nested_element('question', array('id'), array(
'parent', 'name', 'questiontext', 'questiontextformat',
- 'generalfeedback', 'generalfeedbackformat', 'defaultgrade', 'penalty',
+ 'generalfeedback', 'generalfeedbackformat', 'defaultmark', 'penalty',
'qtype', 'length', 'stamp', 'version',
'hidden', 'timecreated', 'timemodified', 'createdby', 'modifiedby'));
// attach qtype plugin structure to $question element, only one allowed
$this->add_plugin_structure('qtype', $question, false);
+ $qhints = new backup_nested_element('question_hints');
+
+ $qhint = new backup_nested_element('question_hint', array('id'), array(
+ 'hint', 'hintformat', 'shownumcorrect', 'clearwrong', 'options'));
+
// Build the tree
$qcategories->add_child($qcategory);
$qcategory->add_child($questions);
-
$questions->add_child($question);
+ $question->add_child($qhints);
+ $qhints->add_child($qhint);
// Define the sources
@@ -1696,6 +1700,13 @@ protected function define_structure() {
$question->set_source_table('question', array('category' => backup::VAR_PARENTID));
+ $qhint->set_source_sql('
+ SELECT *
+ FROM {question_hints}
+ WHERE questionid = :questionid
+ ORDER BY id',
+ array('questionid' => backup::VAR_PARENTID));
+
// don't need to annotate ids nor files
// (already done by {@link backup_annotate_all_question_files}
View
28 backup/moodle2/restore_qtype_plugin.class.php
@@ -115,6 +115,23 @@ public function process_question_answer($data) {
$newquestionid = $this->get_new_parentid('question');
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
+ // In the past, there were some sloppily rounded fractions around. Fix them up.
+ $changes = array(
+ '-0.66666' => '-0.6666667',
+ '-0.33333' => '-0.3333333',
+ '-0.16666' => '-0.1666667',
+ '-0.142857' => '-0.1428571',
+ '0.11111' => '0.1111111',
+ '0.142857' => '0.1428571',
+ '0.16666' => '0.1666667',
+ '0.33333' => '0.3333333',
+ '0.333333' => '0.3333333',
+ '0.66666' => '0.6666667',
+ );
+ if (array_key_exists($data->fraction, $changes)) {
+ $data->fraction = $changes[$data->fraction];
+ }
+
// If the question has been created by restore, we need to create its question_answers too
if ($questioncreated) {
// Adjust some columns
@@ -298,11 +315,14 @@ public function process_question_dataset_item($data) {
}
/**
- * Decode one question_states for this qtype (default impl)
+ * Do any re-coding necessary in the student response.
+ * @param int $questionid the new id of the question
+ * @param int $sequencenumber of the step within the qusetion attempt.
+ * @param array the response data from the backup.
+ * @return array the recoded response.
*/
- public function recode_state_answer($state) {
- // By default, return answer unmodified, qtypes needing recode will override this
- return $state->answer;
+ public function recode_response($questionid, $sequencenumber, array $response) {
+ return $response;
}
/**
View
204 backup/moodle2/restore_stepslib.php
@@ -2310,6 +2310,17 @@ protected function process_question($data) {
// we have loaded qcatids there for all parsed questions
$data->category = $this->get_mappingid('question_category', $questionmapping->parentitemid);
+ // In the past, there were some very sloppy values of penalty. Fix them.
+ if ($data->penalty >= 0.33 && $data->penalty <= 0.34) {
+ $data->penalty = 0.3333333;
+ }
+ if ($data->penalty >= 0.66 && $data->penalty <= 0.67) {
+ $data->penalty = 0.6666667;
+ }
+ if ($data->penalty >= 1) {
+ $data->penalty = 1;
+ }
+
$data->timecreated = $this->apply_date_offset($data->timecreated);
$data->timemodified = $this->apply_date_offset($data->timemodified);
@@ -2339,6 +2350,47 @@ protected function process_question($data) {
// step will be in charge of restoring all the question files
}
+ protected function process_question_hint($data) {
+ global $DB;
+
+ $data = (object)$data;
+ $oldid = $data->id;
+
+ // Detect if the question is created or mapped
+ $oldquestionid = $this->get_old_parentid('question');
+ $newquestionid = $this->get_new_parentid('question');
+ $questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
+
+ // If the question has been created by restore, we need to create its question_answers too
+ if ($questioncreated) {
+ // Adjust some columns
+ $data->questionid = $newquestionid;
+ // Insert record
+ $newitemid = $DB->insert_record('question_answers', $data);
+
+ // The question existed, we need to map the existing question_answers
+ } else {
+ // Look in question_answers by answertext matching
+ $sql = 'SELECT id
+ FROM {question_hints}
+ WHERE questionid = ?
+ AND ' . $DB->sql_compare_text('hint', 255) . ' = ' . $DB->sql_compare_text('?', 255);
+ $params = array($newquestionid, $data->hint);
+ $newitemid = $DB->get_field_sql($sql, $params);
+ // If we haven't found the newitemid, something has gone really wrong, question in DB
+ // is missing answers, exception
+ if (!$newitemid) {
+ $info = new stdClass();
+ $info->filequestionid = $oldquestionid;
+ $info->dbquestionid = $newquestionid;
+ $info->hint = $data->hint;
+ throw new restore_step_exception('error_question_hint_missing_in_db', $info);
+ }
+ }
+ // Create mapping (we'll use this intensively when restoring question_states. And also answerfeedback files)
+ $this->set_mapping('question_hint', $oldid, $newitemid);
+ }
+
protected function after_execute() {
global $DB;
@@ -2461,6 +2513,8 @@ protected function define_execution() {
$oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true);
restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'answerfeedback',
$oldctxid, $this->task->get_userid(), 'question_answer', null, $newctxid, true);
+ restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'hint',
+ $oldctxid, $this->task->get_userid(), 'question_hint', null, $newctxid, true);
// Add qtype dependent files
$components = backup_qtype_plugin::get_components_and_fileareas($question->qtype);
foreach ($components as $component => $fileareas) {
@@ -2481,12 +2535,16 @@ protected function define_execution() {
* (like the quiz module), to support qtype plugins, states and sessions
*/
abstract class restore_questions_activity_structure_step extends restore_activity_structure_step {
+ /** @var array question_attempt->id to qtype. */
+ protected $qtypes = array();
+ /** @var array question_attempt->id to questionid. */
+ protected $newquestionids = array();
/**
* Attach below $element (usually attempts) the needed restore_path_elements
- * to restore question_states
+ * to restore question_usages and all they contain.
*/
- protected function add_question_attempts_states($element, &$paths) {
+ protected function add_question_usages($element, &$paths) {
// Check $element is restore_path_element
if (! $element instanceof restore_path_element) {
throw new restore_step_exception('element_must_be_restore_path_element', $element);
@@ -2495,70 +2553,114 @@ protected function add_question_attempts_states($element, &$paths) {
if (!is_array($paths)) {
throw new restore_step_exception('paths_must_be_array', $paths);
}
- $paths[] = new restore_path_element('question_state', $element->get_path() . '/states/state');
+ $paths[] = new restore_path_element('question_usage',
+ $element->get_path() . '/question_usage');
+ $paths[] = new restore_path_element('question_attempt',
+ $element->get_path() . '/question_usage/question_attempts/question_attempt');
+ $paths[] = new restore_path_element('question_attempt_step',
+ $element->get_path() . '/question_usage/question_attempts/question_attempt/steps/step',
+ true);
+ $paths[] = new restore_path_element('question_attempt_step_data',
+ $element->get_path() . '/question_usage/question_attempts/question_attempt/steps/step/response/variable');
+
+ // TODO Put back code for restoring legacy 2.0 backups.
+ // $paths[] = new restore_path_element('question_state', $element->get_path() . '/states/state');
+ // $paths[] = new restore_path_element('question_session', $element->get_path() . '/sessions/session');
}
/**
- * Attach below $element (usually attempts) the needed restore_path_elements
- * to restore question_sessions
+ * Process question_usages
*/
- protected function add_question_attempts_sessions($element, &$paths) {
- // Check $element is restore_path_element
- if (! $element instanceof restore_path_element) {
- throw new restore_step_exception('element_must_be_restore_path_element', $element);
- }
- // Check $paths is one array
- if (!is_array($paths)) {
- throw new restore_step_exception('paths_must_be_array', $paths);
- }
- $paths[] = new restore_path_element('question_session', $element->get_path() . '/sessions/session');
+ protected function process_question_usage($data) {
+ global $DB;
+
+ // Clear our caches.
+ $this->qtypes = array();
+ $this->newquestionids = array();
+
+ $data = (object)$data;
+ $oldid = $data->id;
+
+ $oldcontextid = $this->get_task()->get_old_contextid();
+ $data->contextid = $this->get_mappingid('context', $this->task->get_old_contextid());
+
+ // Everything ready, insert (no mapping needed)
+ $newitemid = $DB->insert_record('question_usages', $data);
+
+ $this->inform_new_usage_id($newitemid);
+
+ $this->set_mapping('question_usage', $oldid, $newitemid, false);
}
/**
- * Process question_states
+ * When process_question_usage creates the new usage, it calls this method
+ * to let the activity link to the new usage. For example, the quiz uses
+ * this method to set quiz_attempts.uniqueid to the new usage id.
+ * @param integer $newusageid
+ */
+ abstract protected function inform_new_usage_id($newusageid);
+
+ /**
+ * Process question_attempts
*/
- protected function process_question_state($data) {
+ protected function process_question_attempt($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
+ $question = $this->get_mapping('question', $data->questionid);
- // Get complete question mapping, we'll need info
- $question = $this->get_mapping('question', $data->question);
+ $data->questionusageid = $this->get_new_parentid('question_usage');
+ $data->questionid = $question->newitemid;
+ $data->timemodified = $this->apply_date_offset($data->timemodified);
- // In the quiz_attempt mapping we are storing uniqueid
- // and not id, so this gets the correct question_attempt to point to
- $data->attempt = $this->get_new_parentid('quiz_attempt');
- $data->question = $question->newitemid;
- $data->answer = $this->restore_recode_answer($data, $question->info->qtype); // Delegate recoding of answer
- $data->timestamp= $this->apply_date_offset($data->timestamp);
+ $newitemid = $DB->insert_record('question_attempts', $data);
- // Everything ready, insert and create mapping (needed by question_sessions)
- $newitemid = $DB->insert_record('question_states', $data);
- $this->set_mapping('question_state', $oldid, $newitemid);
+ $this->set_mapping('question_attempt', $oldid, $newitemid);
+ $this->qtypes[$newitemid] = $question->info->qtype;
+ $this->newquestionids[$newitemid] = $data->questionid;
}
/**
- * Process question_sessions
+ * Process question_attempt_steps
*/
- protected function process_question_session($data) {
+ protected function process_question_attempt_step($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
- // In the quiz_attempt mapping we are storing uniqueid
- // and not id, so this gets the correct question_attempt to point to
- $data->attemptid = $this->get_new_parentid('quiz_attempt');
- $data->questionid = $this->get_mappingid('question', $data->questionid);
- $data->newest = $this->get_mappingid('question_state', $data->newest);
- $data->newgraded = $this->get_mappingid('question_state', $data->newgraded);
+ // Pull out the response data.
+ $response = array();
+ if (!empty($data->response['variable'])) {
+ foreach ($data->response['variable'] as $variable) {
+ $response[$variable['name']] = $variable['value'];
+ }
+ }
+ unset($data->response);
- // Everything ready, insert (no mapping needed)
- $newitemid = $DB->insert_record('question_sessions', $data);
+ $data->questionattemptid = $this->get_new_parentid('question_attempt');
+ $data->timecreated = $this->apply_date_offset($data->timecreated);
+ $data->userid = $this->get_mappingid('user', $data->userid);
- // Note: question_sessions haven't files associated. On purpose manualcomment is lacking
- // support for them, so we don't need to handle them here.
+ // Everything ready, insert and create mapping (needed by question_sessions)
+ $newitemid = $DB->insert_record('question_attempt_steps', $data);
+ $this->set_mapping('question_attempt_step', $oldid, $newitemid, true);
+
+ // Now process the response data.
+ $qtyperestorer = $this->get_qtype_restorer($this->qtypes[$data->questionattemptid]);
+ if ($qtyperestorer) {
+ $response = $qtyperestorer->recode_response(
+ $this->newquestionids[$data->questionattemptid],
+ $data->sequencenumber, $response);
+ }
+ foreach ($response as $name => $value) {
+ $row = new stdClass();
+ $row->attemptstepid = $newitemid;
+ $row->name = $name;
+ $row->value = $value;
+ $DB->insert_record('question_attempt_step_data', $row, false);
+ }
}
/**
@@ -2581,25 +2683,33 @@ protected function questions_recode_layout($layout) {
}
/**
- * Given one question_states record, return the answer
- * recoded pointing to all the restored stuff
+ * Get the restore_qtype_plugin subclass for a specific question type.
+ * @param string $qtype e.g. multichoice.
+ * @return restore_qtype_plugin instance.
*/
- public function restore_recode_answer($state, $qtype) {
+ protected function get_qtype_restorer($qtype) {
// Build one static cache to store {@link restore_qtype_plugin}
// while we are needing them, just to save zillions of instantiations
// or using static stuff that will break our nice API
static $qtypeplugins = array();
- // If we haven't the corresponding restore_qtype_plugin for current qtype
- // instantiate it and add to cache
if (!isset($qtypeplugins[$qtype])) {
$classname = 'restore_qtype_' . $qtype . '_plugin';
if (class_exists($classname)) {
$qtypeplugins[$qtype] = new $classname('qtype', $qtype, $this);
} else {
- $qtypeplugins[$qtype] = false;
+ $qtypeplugins[$qtype] = null;
}
}
- return !empty($qtypeplugins[$qtype]) ? $qtypeplugins[$qtype]->recode_state_answer($state) : $state->answer;
+ return $qtypeplugins[$qtype];
+ }
+
+ protected function after_execute() {
+ parent::after_execute();
+
+ // Restore any files belonging to responses.
+ foreach (question_engine::get_all_response_file_areas() as $filearea) {
+ $this->add_related_files('question', $filearea, 'question_attempt_step');
+ }
}
}
View
73 enrol/externallib.php
@@ -43,9 +43,9 @@ public static function get_enrolled_users_parameters() {
return new external_function_parameters(
array(
'courseid' => new external_value(PARAM_INT, 'Course id'),
- 'withcapability' => new external_value(PARAM_CAPABILITY, 'User should have this capability'),
- 'groupid' => new external_value(PARAM_INT, 'Group id, null means all groups'),
- 'onlyactive' => new external_value(PARAM_INT, 'True means only active, false means all participants'),
+ 'withcapability' => new external_value(PARAM_CAPABILITY, 'User should have this capability', VALUE_DEFAULT, null),
+ 'groupid' => new external_value(PARAM_INT, 'Group id, null means all groups', VALUE_DEFAULT, null),
+ 'onlyactive' => new external_value(PARAM_INT, 'True means only active, false means all participants', VALUE_DEFAULT, 0),
)
);
}
@@ -59,12 +59,17 @@ public static function get_enrolled_users_parameters() {
* @param bool $onlyactive
* @return array of course participants
*/
- public static function get_enrolled_users($courseid, $withcapability, $groupid, $onlyactive) {
- global $DB;
+ public static function get_enrolled_users($courseid, $withcapability = null, $groupid = null, $onlyactive = false) {
+ global $DB, $CFG, $USER;
// Do basic automatic PARAM checks on incoming data, using params description
// If any problems are found then exceptions are thrown with helpful error messages
- $params = self::validate_parameters(self::get_enrolled_users_parameters(), array('courseid'=>$courseid, 'withcapability'=>$withcapability, 'groupid'=>$groupid, 'onlyactive'=>$onlyactive));
+ $params = self::validate_parameters(self::get_enrolled_users_parameters(), array(
+ 'courseid'=>$courseid,
+ 'withcapability'=>$withcapability,
+ 'groupid'=>$groupid,
+ 'onlyactive'=>$onlyactive)
+ );
$coursecontext = get_context_instance(CONTEXT_COURSE, $params['courseid']);
if ($courseid == SITEID) {
@@ -76,11 +81,10 @@ public static function get_enrolled_users($courseid, $withcapability, $groupid,
try {
self::validate_context($context);
} catch (Exception $e) {
- $exceptionparam = new stdClass();
- $exceptionparam->message = $e->getMessage();
- $exceptionparam->courseid = $params['courseid'];
- throw new moodle_exception(
- get_string('errorcoursecontextnotvalid' , 'webservice', $exceptionparam));
+ $exceptionparam = new stdClass();
+ $exceptionparam->message = $e->getMessage();
+ $exceptionparam->courseid = $params['courseid'];
+ throw new moodle_exception(get_string('errorcoursecontextnotvalid' , 'webservice', $exceptionparam));
}
if ($courseid == SITEID) {
@@ -92,28 +96,46 @@ public static function get_enrolled_users($courseid, $withcapability, $groupid,
if ($withcapability) {
require_capability('moodle/role:review', $coursecontext);
}
- if ($groupid) {
- if (groups_is_member($groupid)) {
- require_capability('moodle/site:accessallgroups', $coursecontext);
- }
+ if ($groupid && groups_is_member($groupid)) {
+ require_capability('moodle/site:accessallgroups', $coursecontext);
}
if ($onlyactive) {
require_capability('moodle/course:enrolreview', $coursecontext);
}
- list($sql, $params) = get_enrolled_sql($coursecontext, $withcapability, $groupid, $onlyactive);
- $sql = "SELECT DISTINCT ue.userid, e.courseid
+ list($sqlparams, $params) = get_enrolled_sql($coursecontext, $withcapability, $groupid, $onlyactive);
+ $sql = "SELECT ue.userid, e.courseid, u.firstname, u.lastname, u.username, c.id as usercontextid
FROM {user_enrolments} ue
JOIN {enrol} e ON (e.id = ue.enrolid)
- WHERE e.courseid = :courseid AND ue.userid IN ($sql)";
+ JOIN {user} u ON (ue.userid = u.id)
+ JOIN {context} c ON (u.id = c.instanceid AND contextlevel = " . CONTEXT_USER . ")
+ WHERE e.courseid = :courseid AND ue.userid IN ($sqlparams)
+ GROUP BY ue.userid, e.courseid, u.firstname, u.lastname, u.username, c.id";
$params['courseid'] = $courseid;
-
$enrolledusers = $DB->get_records_sql($sql, $params);
-
$result = array();
+ $isadmin = is_siteadmin($USER);
+ $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
foreach ($enrolledusers as $enrolleduser) {
- $result[] = array('courseid' => $enrolleduser->courseid,
- 'userid' => $enrolleduser->userid);
+ $profilimgurl = moodle_url::make_pluginfile_url($enrolleduser->usercontextid, 'user', 'icon', NULL, '/', 'f1');
+ $profilimgurlsmall = moodle_url::make_pluginfile_url($enrolleduser->usercontextid, 'user', 'icon', NULL, '/', 'f2');
+ $resultuser = array(
+ 'courseid' => $enrolleduser->courseid,
+ 'userid' => $enrolleduser->userid,
+ 'fullname' => fullname($enrolleduser),
+ 'profileimgurl' => $profilimgurl->out(false),
+ 'profileimgurlsmall' => $profilimgurlsmall->out(false)
+ );
+ // check if we can return username
+ if ($isadmin) {
+ $resultuser['username'] = $enrolleduser->username;
+ }
+ // check if we can return first and last name
+ if ($isadmin or $canviewfullnames) {
+ $resultuser['firstname'] = $enrolleduser->firstname;
+ $resultuser['lastname'] = $enrolleduser->lastname;
+ }
+ $result[] = $resultuser;
}
return $result;
@@ -129,12 +151,17 @@ public static function get_enrolled_users_returns() {
array(
'courseid' => new external_value(PARAM_INT, 'id of course'),
'userid' => new external_value(PARAM_INT, 'id of user'),
+ 'firstname' => new external_value(PARAM_RAW, 'first name of user', VALUE_OPTIONAL),
+ 'lastname' => new external_value(PARAM_RAW, 'last name of user', VALUE_OPTIONAL),
+ 'fullname' => new external_value(PARAM_RAW, 'fullname of user'),
+ 'username' => new external_value(PARAM_RAW, 'username of user', VALUE_OPTIONAL),
+ 'profileimgurl' => new external_value(PARAM_URL, 'url of the profile image'),
+ 'profileimgurlsmall' => new external_value(PARAM_URL, 'url of the profile image (small version)')
)
)
);
}
-
/**
* Returns description of method parameters
* @return external_function_parameters
View
41 lang/en/admin.php
@@ -51,7 +51,6 @@
$string['allowrenames'] = 'Allow renames';
$string['allowthemechangeonurl'] = 'Allow theme changes in the URL';
$string['allowuserblockhiding'] = 'Allow users to hide blocks';
-$string['allowusermailcharset'] = 'Allow user to select character set';
$string['allowuserswitchrolestheycantassign'] = 'Allow users without the assign roles capability to switch roles';
$string['allowuserthemes'] = 'Allow user themes';
$string['antivirus'] = 'Anti-Virus';
@@ -133,7 +132,6 @@
$string['configallowswitch'] = 'Select which roles a user may switch to, based on which roles they already have. In addition to an entry in this table, a user must also have the moodle/role:switchroles capability to be able to switch.<br />Note that it is only possible to switch to roles that have the moodle/course:view capability, and that do not have the moodle/site:doanything capability, so some columns in this table are disabled.';
$string['configallowthemechangeonurl'] = 'If enabled, the theme can be changed by adding theme={themename} to any Moodle URL.';
$string['configallowuserblockhiding'] = 'Do you want to allow users to hide/show side blocks throughout this site? This feature uses Javascript and cookies to remember the state of each collapsible block, and only affects the user\'s own view.';
-$string['configallowusermailcharset'] = 'Enabling this, every user in the site will be able to specify his own charset for email.';
$string['configallowuserswitchrolestheycantassign'] = 'By default, moodle/role:assign is required for users to switch roles. Enabling this setting removes this requirement, and results in the roles available in the "Switch role to" dropdown menu being determined by settings in the "Allow role assignments" table only.
It is recommended that the settings in the "Allow role assignments" table do not allow users to switch to a role with more capabilities than their existing role.';
$string['configallowuserthemes'] = 'If you enable this, then users will be allowed to set their own themes. User themes override site themes (but not course themes)';
@@ -187,6 +185,7 @@
$string['configdeleteincompleteusers'] = 'After this period, old not fully setup accounts are deleted.';
$string['configdeleteunconfirmed'] = 'If you are using email authentication, this is the period within which a response will be accepted from users. After this period, old unconfirmed accounts are deleted.';
$string['configdenyemailaddresses'] = 'To deny email addresses from particular domains list them here in the same way. All other domains will be accepted. To deny subdomains add the domain with a preceding \'.\'. eg <strong>hotmail.com yahoo.co.uk .live.com</strong>';
+$string['configenabledevicedetection'] = 'Enables detection of mobiles, smartphones, tablets or default devices (desktop PCs, laptops, etc) for the application of themes and other features.';
$string['configdigestmailtime'] = 'People who choose to have emails sent to them in digest form will be emailed the digest daily. This setting controls which time of day the daily mail will be sent (the next cron that runs after this hour will send it).';
$string['configdisableuserimages'] = 'Disable the ability for users to change user profile images.';
$string['configdisplayloginfailures'] = 'This will display information to selected users about previous failed logins.';
@@ -202,6 +201,7 @@
$string['configenableglobalsearch'] = 'This setting enables global text searching in resources and activities, it is not compatible with PHP 4.';
$string['configenablegroupmembersonly'] = 'If enabled, access to activities can be restricted to group members only. This may result in an increased server load. In addition, gradebook categories must be set up in a certain way to ensure that activities are hidden from non-group members.';
$string['configenablehtmlpurifier'] = 'Use HTML Purifier instead of KSES for cleaning of untrusted text. HTML Purifier is actively developed and is believed to be more secure, but it is more resource intensive. Expect minor visual differences in the resulting html code. Please note that embed and object tags can not be enabled, MathML tags and old lang tags are not supported.';
+$string['configenablemobilewebservice'] = 'Enable mobile service for the official Moodle app or other app requesting it. For more information, read the {$a}';
$string['configenablerssfeeds'] = 'This switch will enable RSS feeds from across the site. To actually see any change you will need to enable RSS feeds in the individual modules too - go to the Modules settings under Admin Configuration.';
$string['configenablerssfeedsdisabled'] = 'It is not available because RSS feeds are disabled in all the Site. To enable them, go to the Variables settings under Admin Configuration.';
$string['configenablerssfeedsdisabled2'] = 'RSS feeds are disabled at the server level. You need to enable them first in Server/RSS.';