Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge branch 'master' of https://github.com/moodle/moodle

  • Loading branch information...
commit ae4a9ae7792c16d671ae9264edf252055ed94c4e 2 parents e891c68 + 4f7f2a8
Yang authored May 22, 2012

Showing 213 changed files with 12,492 additions and 3,832 deletions. Show diff stats Hide diff stats

  1. 4  admin/index.php
  2. 51  admin/renderer.php
  3. 16  admin/roles/usersroles.php
  4. 30  admin/settings/server.php
  5. 2  admin/tool/dbtransfer/database_transfer_form.php
  6. 27  admin/tool/innodb/index.php
  7. 2  admin/user/user_bulk_download.php
  8. 252  admin/webservice/testclient_forms.php
  9. 9  backup/converter/moodle1/tests/lib_test.php
  10. 15  backup/moodle2/backup_stepslib.php
  11. 9  backup/moodle2/restore_final_task.class.php
  12. 93  backup/moodle2/restore_stepslib.php
  13. 12  backup/util/plan/restore_structure_step.class.php
  14. 33  calendar/lib.php
  15. 7  config-dist.php
  16. 888  course/dndupload.js
  17. 39  course/dndupload.php
  18. 655  course/dnduploadlib.php
  19. 1  course/edit.php
  20. 27  course/editcategory.php
  21. 30  course/editsection.php
  22. 152  course/editsection_form.php
  23. 843  course/externallib.php
  24. 98  course/format/renderer.php
  25. 5  course/format/topics/format.js
  26. 3  course/format/weeks/format.js
  27. 175  course/lib.php
  28. 16  course/moodleform_mod.php
  29. 151  course/renderer.php
  30. 36  course/rest.php
  31. 0  course/style.css
  32. 38  course/view.php
  33. 185  course/yui/modchooser/modchooser.js
  34. 128  course/yui/toolboxes/toolboxes.js
  35. 4  grade/export/grade_export_form.php
  36. 12  grade/export/lib.php
  37. 3  grade/export/ods/export.php
  38. 1  grade/export/ods/grade_export_ods.php
  39. 2  grade/export/ods/index.php
  40. 3  grade/export/txt/export.php
  41. 10  grade/export/txt/grade_export_txt.php
  42. 2  grade/export/txt/index.php
  43. 3  grade/export/xls/export.php
  44. 1  grade/export/xls/grade_export_xls.php
  45. 2  grade/export/xls/index.php
  46. 3  grade/export/xml/export.php
  47. 1  grade/export/xml/grade_export_xml.php
  48. 2  grade/export/xml/index.php
  49. 24  grade/lib.php
  50. 3  grade/report/grader/lib.php
  51. 4  group/delete.php
  52. 554  group/externallib.php
  53. 4  group/group.php
  54. 23  group/group_form.php
  55. 7  group/grouping.php
  56. 23  group/grouping_form.php
  57. 10  group/groupings.php
  58. 19  group/import.php
  59. 5  group/index.php
  60. 24  group/lib.php
  61. 30  group/module.js
  62. 14  index.php
  63. 3  install/lang/ar/admin.php
  64. 2  install/lang/et/admin.php
  65. 37  install/lang/rm_surs/admin.php
  66. 8  install/lang/sr_cr/install.php
  67. 6  install/lang/sr_lt/install.php
  68. 1  install/lang/zh_cn/install.php
  69. 15  iplookup/lib.php
  70. 86  iplookup/tests/geoip_test.php
  71. 60  iplookup/tests/geoplugin_test.php
  72. 4  lang/en/admin.php
  73. 14  lang/en/completion.php
  74. 12  lang/en/condition.php
  75. 6  lang/en/error.php
  76. 2  lang/en/grades.php
  77. 2  lang/en/group.php
  78. 2  lang/en/install.php
  79. 26  lang/en/moodle.php
  80. 9  lang/en/question.php
  81. 1  lang/en/webservice.php
  82. 661  lib/conditionlib.php
  83. 8  lib/cronlib.php
  84. 50  lib/db/install.xml
  85. 119  lib/db/services.php
  86. 91  lib/db/upgrade.php
  87. 11  lib/dml/mysqli_native_moodle_database.php
  88. 8  lib/dml/pgsql_native_moodle_database.php
  89. 6  lib/dml/sqlsrv_native_moodle_database.php
  90. 8  lib/dml/tests/dml_test.php
  91. 1  lib/editor/tinymce/lang/en/editor_tinymce.php
  92. 16  lib/editor/tinymce/lib.php
  93. 5  lib/editor/tinymce/settings.php
  94. 4  lib/editor/tinymce/version.php
  95. 4  lib/excel/test.php
  96. 20  lib/externallib.php
  97. 2  lib/filelib.php
  98. 1  lib/form/yui/dateselector/dateselector.js
  99. 73  lib/grouplib.php
  100. 363  lib/modinfolib.php
  101. 64  lib/moodlelib.php
  102. 86  lib/navigationlib.php
  103. 6  lib/outputrenderers.php
  104. 339  lib/phpunit/classes/advanced_testcase.php
  105. 85  lib/phpunit/classes/arraydataset.php
  106. 78  lib/phpunit/classes/basic_testcase.php
  107. 112  lib/phpunit/classes/block_generator.php
  108. 544  lib/phpunit/classes/data_generator.php
  109. 136  lib/phpunit/classes/database_driver_testcase.php
  110. 67  lib/phpunit/classes/hint_resultprinter.php
  111. 141  lib/phpunit/classes/module_generator.php
  112. 193  lib/phpunit/classes/unittestcase.php
  113. 1,136  lib/phpunit/classes/util.php
  114. 729  lib/phpunit/generatorlib.php
  115. 1,807  lib/phpunit/lib.php
  116. 215  lib/{tests/phpunit_test.php → phpunit/tests/advanced_test.php}
  117. 155  lib/phpunit/tests/basic_test.php
  118. 0  lib/{ → phpunit}/tests/fixtures/sample_dataset.csv
  119. 0  lib/{ → phpunit}/tests/fixtures/sample_dataset.xml
  120. 88  lib/phpunit/tests/generator_test.php
  121. 4  lib/pluginlib.php
  122. 8  lib/setup.php
  123. 9  lib/setuplib.php
  124. 21  lib/tests/code_test.php
  125. 384  lib/tests/conditionlib_test.php
  126. 174  lib/tests/grouplib_test.php
  127. 41  lib/tests/moodlelib_test.php
  128. 5  lib/tests/pagelib_test.php
  129. 2  lib/tests/repositorylib_test.php
  130. 202  lib/yui/chooserdialogue/chooserdialogue.js
  131. 5  mod/assign/adminlib.php
  132. 2  mod/assign/assignmentplugin.php
  133. 30  mod/assign/gradingtable.php
  134. 7  mod/assign/lang/en/assign.php
  135. 4  mod/assign/lib.php
  136. 67  mod/assign/locallib.php
  137. 3  mod/assign/styles.css
  138. 51  mod/assign/upgradelib.php
  139. 2  mod/assignment/lang/en/assignment.php
  140. 4  mod/assignment/tests/generator_test.php
  141. 1  mod/chat/gui_basic/index.php
  142. 14  mod/chat/lang/en/chat.php
  143. 31  mod/chat/lib.php
  144. 11  mod/choice/lang/en/choice.php
  145. 15  mod/data/lang/en/data.php
  146. 135  mod/data/lib.php
  147. 116  mod/data/locallib.php
  148. 6  mod/data/view.php
  149. 4  mod/feedback/edit_form.php
  150. 2  mod/feedback/export.php
  151. 12  mod/feedback/lang/en/feedback.php
  152. 9  mod/feedback/lib.php
  153. 8  mod/folder/lang/en/folder.php
  154. 48  mod/folder/lib.php
  155. 23  mod/forum/lang/en/forum.php
  156. 69  mod/forum/lib.php
  157. 116  mod/forum/locallib.php
  158. 19  mod/glossary/lang/en/glossary.php
  159. 76  mod/glossary/lib.php
  160. 125  mod/glossary/locallib.php
  161. 7  mod/imscp/lang/en/imscp.php
  162. 9  mod/label/lang/en/label.php
  163. 14  mod/lesson/lang/en/lesson.php
  164. 26  mod/lesson/lib.php
  165. 4  mod/lesson/locallib.php
  166. 29  mod/lti/lang/en/lti.php
  167. 15  mod/lti/lib.php
  168. 6  mod/lti/typessettings.php
  169. 11  mod/page/lang/en/page.php
  170. 43  mod/page/lib.php
  171. 137  mod/quiz/db/upgrade.php
  172. 2  mod/quiz/editlib.php
  173. 16  mod/quiz/lang/en/quiz.php
  174. 24  mod/quiz/lib.php
  175. 21  mod/quiz/locallib.php
  176. 11  mod/resource/lang/en/resource.php
  177. 37  mod/resource/lib.php
  178. 10  mod/scorm/lang/en/scorm.php
  179. 3  mod/scorm/module.js
  180. 3  mod/survey/lang/en/survey.php
  181. 33  mod/survey/lib.php
  182. 5  mod/url/lang/en/url.php
  183. 48  mod/url/lib.php
  184. 12  mod/wiki/lang/en/wiki.php
  185. 17  mod/wiki/lib.php
  186. 2  mod/wiki/locallib.php
  187. 11  mod/workshop/form/rubric/lib.php
  188. 2  mod/workshop/form/rubric/tests/lib_test.php
  189. 8  mod/workshop/lang/en/workshop.php
  190. 43  mod/workshop/lib.php
  191. 12  phpunit.xml.dist
  192. BIN  pix/t/editstring.png
  193. 4  question/editlib.php
  194. 757  question/engine/simpletest/helpers.php
  195. 7  question/engine/tests/helpers.php
  196. 5  question/engine/upgrade/tests/helper.php
  197. 74  question/preview.php
  198. 1  question/type/calculated/questiontype.php
  199. 60  question/type/match/tests/walkthrough_test.php
  200. 58  question/type/multianswer/tests/upgradelibnewqe_test.php
  201. 8  report/completion/index.php
  202. 2  report/progress/index.php
  203. 36  repository/upload/lib.php
  204. 103  theme/base/style/core.css
  205. 32  theme/base/style/course.css
  206. 4  theme/base/style/question.css
  207. 6  theme/formal_white/style/core.css
  208. 7  theme/formal_white/style/formal_white.css
  209. 2  user/filesedit.php
  210. 4  version.php
  211. 3  webservice/rest/locallib.php
  212. 94  webservice/soap/locallib.php
  213. 18  webservice/xmlrpc/locallib.php
4  admin/index.php
@@ -240,7 +240,9 @@
240 240
 
241 241
         if ($fetchupdates) {
242 242
             // no sesskey support guaranteed here
243  
-            available_update_checker::instance()->fetch();
  243
+            if (empty($CFG->disableupdatenotifications)) {
  244
+                available_update_checker::instance()->fetch();
  245
+            }
244 246
             redirect($reloadurl);
245 247
         }
246 248
 
51  admin/renderer.php
@@ -174,6 +174,7 @@ public function upgrade_environment_page($release, $envstatus, $environment_resu
174 174
      */
175 175
     public function upgrade_plugin_check_page(plugin_manager $pluginman, available_update_checker $checker,
176 176
             $version, $showallplugins, $reloadurl, $continueurl) {
  177
+        global $CFG;
177 178
 
178 179
         $output = '';
179 180
 
@@ -181,14 +182,16 @@ public function upgrade_plugin_check_page(plugin_manager $pluginman, available_u
181 182
         $output .= $this->box_start('generalbox');
182 183
         $output .= $this->container_start('generalbox', 'notice');
183 184
         $output .= html_writer::tag('p', get_string('pluginchecknotice', 'core_plugin'));
184  
-        $output .= $this->container_start('checkforupdates');
185  
-        $output .= $this->single_button(new moodle_url($reloadurl, array('fetchupdates' => 1)), get_string('checkforupdates', 'core_plugin'));
186  
-        if ($timefetched = $checker->get_last_timefetched()) {
187  
-            $output .= $this->container(get_string('checkforupdateslast', 'core_plugin',
188  
-                userdate($timefetched, get_string('strftimedatetime', 'core_langconfig'))));
  185
+        if (empty($CFG->disableupdatenotifications)) {
  186
+            $output .= $this->container_start('checkforupdates');
  187
+            $output .= $this->single_button(new moodle_url($reloadurl, array('fetchupdates' => 1)), get_string('checkforupdates', 'core_plugin'));
  188
+            if ($timefetched = $checker->get_last_timefetched()) {
  189
+                $output .= $this->container(get_string('checkforupdateslast', 'core_plugin',
  190
+                    userdate($timefetched, get_string('strftimedatetime', 'core_langconfig'))));
  191
+            }
  192
+            $output .= $this->container_end();
189 193
         }
190 194
         $output .= $this->container_end();
191  
-        $output .= $this->container_end();
192 195
 
193 196
         $output .= $this->plugins_check_table($pluginman, $version, array('full' => $showallplugins));
194 197
         $output .= $this->box_end();
@@ -227,11 +230,12 @@ public function upgrade_plugin_check_page(plugin_manager $pluginman, available_u
227 230
      */
228 231
     public function admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed,
229 232
             $cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch) {
  233
+        global $CFG;
230 234
         $output = '';
231 235
 
232 236
         $output .= $this->header();
233 237
         $output .= $this->maturity_info($maturity);
234  
-        $output .= $this->available_updates($availableupdates, $availableupdatesfetch);
  238
+        $output .= empty($CFG->disableupdatenotifications) ? $this->available_updates($availableupdates, $availableupdatesfetch) : '';
235 239
         $output .= $this->insecure_dataroot_warning($insecuredataroot);
236 240
         $output .= $this->display_errors_warning($errorsdisplayed);
237 241
         $output .= $this->cron_overdue_warning($cronoverdue);
@@ -256,19 +260,23 @@ public function admin_notifications_page($maturity, $insecuredataroot, $errorsdi
256 260
      * @return string HTML to output.
257 261
      */
258 262
     public function plugin_management_page(plugin_manager $pluginman, available_update_checker $checker) {
  263
+        global $CFG;
  264
+
259 265
         $output = '';
260 266
 
261 267
         $output .= $this->header();
262 268
         $output .= $this->heading(get_string('pluginsoverview', 'core_admin'));
263 269
         $output .= $this->plugins_overview_panel($pluginman);
264 270
 
265  
-        $output .= $this->container_start('checkforupdates');
266  
-        $output .= $this->single_button(new moodle_url($this->page->url, array('fetchremote' => 1)), get_string('checkforupdates', 'core_plugin'));
267  
-        if ($timefetched = $checker->get_last_timefetched()) {
268  
-            $output .= $this->container(get_string('checkforupdateslast', 'core_plugin',
269  
-                userdate($timefetched, get_string('strftimedatetime', 'core_langconfig'))));
  271
+        if (empty($CFG->disableupdatenotifications)) {
  272
+            $output .= $this->container_start('checkforupdates');
  273
+            $output .= $this->single_button(new moodle_url($this->page->url, array('fetchremote' => 1)), get_string('checkforupdates', 'core_plugin'));
  274
+            if ($timefetched = $checker->get_last_timefetched()) {
  275
+                $output .= $this->container(get_string('checkforupdateslast', 'core_plugin',
  276
+                    userdate($timefetched, get_string('strftimedatetime', 'core_langconfig'))));
  277
+            }
  278
+            $output .= $this->container_end();
270 279
         }
271  
-        $output .= $this->container_end();
272 280
 
273 281
         $output .= $this->box($this->plugins_control_panel($pluginman), 'generalbox');
274 282
         $output .= $this->footer();
@@ -466,7 +474,10 @@ protected function available_updates($updates, $fetch) {
466 474
                 $updateinfo .= $this->moodle_available_update_info($update);
467 475
             }
468 476
         } else {
469  
-            $updateinfo .= $this->heading(get_string('updateavailablenot', 'core_admin'), 3);
  477
+            $now = time();
  478
+            if ($fetch and ($fetch <= $now) and ($now - $fetch < HOURSECS)) {
  479
+                $updateinfo .= $this->heading(get_string('updateavailablenot', 'core_admin'), 3);
  480
+            }
470 481
         }
471 482
 
472 483
         $updateinfo .= $this->container_start('checkforupdates');
@@ -559,6 +570,8 @@ function upgrade_reload($url) {
559 570
      * @return string HTML code
560 571
      */
561 572
     public function plugins_check_table(plugin_manager $pluginman, $version, array $options = null) {
  573
+        global $CFG;
  574
+
562 575
         $plugininfo = $pluginman->get_plugins();
563 576
 
564 577
         if (empty($plugininfo)) {
@@ -641,7 +654,7 @@ public function plugins_check_table(plugin_manager $pluginman, $version, array $
641 654
                 $status = get_string('status_' . $statuscode, 'core_plugin');
642 655
 
643 656
                 $availableupdates = $plugin->available_updates();
644  
-                if (!empty($availableupdates)) {
  657
+                if (!empty($availableupdates) and empty($CFG->disableupdatenotifications)) {
645 658
                     foreach ($availableupdates as $availableupdate) {
646 659
                         $status .= $this->plugin_available_update_info($availableupdate);
647 660
                     }
@@ -771,6 +784,8 @@ protected function required_column(plugininfo_base $plugin, plugin_manager $plug
771 784
      * @return string as usually
772 785
      */
773 786
     public function plugins_overview_panel(plugin_manager $pluginman) {
  787
+        global $CFG;
  788
+
774 789
         $plugininfo = $pluginman->get_plugins();
775 790
 
776 791
         $numtotal = $numdisabled = $numextension = $numupdatable = 0;
@@ -787,7 +802,7 @@ public function plugins_overview_panel(plugin_manager $pluginman) {
787 802
                 if (!$plugin->is_standard()) {
788 803
                     $numextension++;
789 804
                 }
790  
-                if ($plugin->available_updates()) {
  805
+                if (empty($CFG->disableupdatenotifications) and $plugin->available_updates()) {
791 806
                     $numupdatable++;
792 807
                 }
793 808
             }
@@ -813,6 +828,8 @@ public function plugins_overview_panel(plugin_manager $pluginman) {
813 828
      * @return string HTML code
814 829
      */
815 830
     public function plugins_control_panel(plugin_manager $pluginman) {
  831
+        global $CFG;
  832
+
816 833
         $plugininfo = $pluginman->get_plugins();
817 834
 
818 835
         if (empty($plugininfo)) {
@@ -916,7 +933,7 @@ public function plugins_control_panel(plugin_manager $pluginman) {
916 933
                 }
917 934
 
918 935
                 $updateinfo = '';
919  
-                if (is_array($plugin->available_updates())) {
  936
+                if (empty($CFG->disableupdatenotifications) and is_array($plugin->available_updates())) {
920 937
                     foreach ($plugin->available_updates() as $availableupdate) {
921 938
                         $updateinfo .= $this->plugin_available_update_info($availableupdate);
922 939
                     }
16  admin/roles/usersroles.php
@@ -54,6 +54,17 @@
54 54
     print_error('nopermissions', 'error', '', get_string('checkpermissions', 'role'));
55 55
 }
56 56
 
  57
+if ($userid != $USER->id) {
  58
+    // If its not the current user we need to extend the navigation for that user to ensure
  59
+    // their navigation is loaded and this page found upon it.
  60
+    $PAGE->navigation->extend_for_user($user);
  61
+}
  62
+if ($course->id != $SITE->id || $userid != $USER->id) {
  63
+    // If we're within a course OR if we're viewing another user then we need to include the
  64
+    // settings base on the navigation to ensure that the navbar will contain the users name.
  65
+    $PAGE->navbar->includesettingsbase = true;
  66
+}
  67
+
57 68
 /// Now get the role assignments for this user.
58 69
 $sql = "SELECT
59 70
         ra.id, ra.userid, ra.contextid, ra.roleid, ra.component, ra.itemid,
@@ -120,14 +131,9 @@
120 131
 $PAGE->set_title($title);
121 132
 if ($courseid != SITEID) {
122 133
     $PAGE->set_heading($fullname);
123  
-    if (has_capability('moodle/course:viewparticipants', $coursecontext)) {
124  
-        $PAGE->navbar->add(get_string('participants'),new moodle_url('/user/index.php', array('id'=>$courseid)));
125  
-    }
126 134
 } else {
127 135
     $PAGE->set_heading($course->fullname);
128 136
 }
129  
-$PAGE->navbar->add($fullname, new moodle_url("$CFG->wwwroot/user/view.php", array('id'=>$userid,'course'=>$courseid)));
130  
-$PAGE->navbar->add($straction);
131 137
 echo $OUTPUT->header();
132 138
 echo $OUTPUT->heading($title, 3);
133 139
 echo $OUTPUT->box_start('generalbox boxaligncenter boxwidthnormal');
30  admin/settings/server.php
@@ -222,19 +222,21 @@
222 222
 $ADMIN->add('server', new admin_externalpage('adminregistration', new lang_string('registration','admin'), "$CFG->wwwroot/$CFG->admin/registration/index.php"));
223 223
 
224 224
 // "update notifications" settingpage
225  
-$temp = new admin_settingpage('updatenotifications', new lang_string('updatenotifications', 'core_admin'));
226  
-$temp->add(new admin_setting_configcheckbox('updateautocheck', new lang_string('updateautocheck', 'core_admin'),
227  
-                                            new lang_string('updateautocheck_desc', 'core_admin'), 1));
228  
-$temp->add(new admin_setting_configselect('updateminmaturity', new lang_string('updateminmaturity', 'core_admin'),
229  
-                                          new lang_string('updateminmaturity_desc', 'core_admin'), MATURITY_STABLE,
230  
-                                          array(
231  
-                                              MATURITY_ALPHA  => new lang_string('maturity'.MATURITY_ALPHA, 'core_admin'),
232  
-                                              MATURITY_BETA   => new lang_string('maturity'.MATURITY_BETA, 'core_admin'),
233  
-                                              MATURITY_RC     => new lang_string('maturity'.MATURITY_RC, 'core_admin'),
234  
-                                              MATURITY_STABLE => new lang_string('maturity'.MATURITY_STABLE, 'core_admin'),
235  
-                                          )));
236  
-$temp->add(new admin_setting_configcheckbox('updatenotifybuilds', new lang_string('updatenotifybuilds', 'core_admin'),
237  
-                                            new lang_string('updatenotifybuilds_desc', 'core_admin'), 0));
238  
-$ADMIN->add('server', $temp);
  225
+if (empty($CFG->disableupdatenotifications)) {
  226
+    $temp = new admin_settingpage('updatenotifications', new lang_string('updatenotifications', 'core_admin'));
  227
+    $temp->add(new admin_setting_configcheckbox('updateautocheck', new lang_string('updateautocheck', 'core_admin'),
  228
+                                                new lang_string('updateautocheck_desc', 'core_admin'), 1));
  229
+    $temp->add(new admin_setting_configselect('updateminmaturity', new lang_string('updateminmaturity', 'core_admin'),
  230
+                                              new lang_string('updateminmaturity_desc', 'core_admin'), MATURITY_STABLE,
  231
+                                              array(
  232
+                                                  MATURITY_ALPHA  => new lang_string('maturity'.MATURITY_ALPHA, 'core_admin'),
  233
+                                                  MATURITY_BETA   => new lang_string('maturity'.MATURITY_BETA, 'core_admin'),
  234
+                                                  MATURITY_RC     => new lang_string('maturity'.MATURITY_RC, 'core_admin'),
  235
+                                                  MATURITY_STABLE => new lang_string('maturity'.MATURITY_STABLE, 'core_admin'),
  236
+                                              )));
  237
+    $temp->add(new admin_setting_configcheckbox('updatenotifybuilds', new lang_string('updatenotifybuilds', 'core_admin'),
  238
+                                                new lang_string('updatenotifybuilds_desc', 'core_admin'), 0));
  239
+    $ADMIN->add('server', $temp);
  240
+}
239 241
 
240 242
 } // end of speedup
2  admin/tool/dbtransfer/database_transfer_form.php
@@ -39,7 +39,7 @@ function definition() {
39 39
             'pgsql/native',
40 40
             'mssql/native',
41 41
             'oci/native',
42  
-            'sqlite3/pdo',
  42
+            'sqlsrv/native',
43 43
         );
44 44
         $drivers = array();
45 45
         foreach($supported as $driver) {
27  admin/tool/innodb/index.php
@@ -42,29 +42,40 @@
42 42
     notice('This function is for MySQL databases only!', new moodle_url('/admin/'));
43 43
 }
44 44
 
  45
+$prefix = str_replace('_', '\\_', $DB->get_prefix()).'%';
  46
+$sql = "SHOW TABLE STATUS WHERE Name LIKE ? AND Engine <> 'InnoDB'";
  47
+$rs = $DB->get_recordset_sql($sql, array($prefix));
  48
+if (!$rs->valid()) {
  49
+    $rs->close();
  50
+    echo $OUTPUT->box('<p>All tables are already using InnoDB database engine.</p>');
  51
+    echo $OUTPUT->continue_button('/admin/');
  52
+    echo $OUTPUT->footer();
  53
+    die;
  54
+}
  55
+
45 56
 if (data_submitted() and $confirm and confirm_sesskey()) {
46 57
 
47 58
     echo $OUTPUT->notification('Please be patient and wait for this to complete...', 'notifysuccess');
48 59
 
49 60
     set_time_limit(0);
50 61
 
51  
-    if ($tables = $DB->get_tables()) {
  62
+    foreach ($rs as $table) {
52 63
         $DB->set_debug(true);
53  
-        foreach ($tables as $table) {
54  
-            $fulltable = $DB->get_prefix().$table;
55  
-            try {
56  
-                $DB->change_database_structure("ALTER TABLE $fulltable ENGINE=INNODB");
57  
-            } catch (moodle_exception $e) {
58  
-                echo $OUTPUT->notification(s($e->getMessage()).'<br />'.s($e->debuginfo));
59  
-            }
  64
+        $fulltable = $table->name;
  65
+        try {
  66
+            $DB->change_database_structure("ALTER TABLE $fulltable ENGINE=INNODB");
  67
+        } catch (moodle_exception $e) {
  68
+            echo $OUTPUT->notification(s($e->getMessage()).'<br />'.s($e->debuginfo));
60 69
         }
61 70
         $DB->set_debug(false);
62 71
     }
  72
+    $rs->close();
63 73
     echo $OUTPUT->notification('... done.', 'notifysuccess');
64 74
     echo $OUTPUT->continue_button(new moodle_url('/admin/'));
65 75
     echo $OUTPUT->footer();
66 76
 
67 77
 } else {
  78
+    $rs->close();
68 79
     $optionsyes = array('confirm'=>'1', 'sesskey'=>sesskey());
69 80
     $formcontinue = new single_button(new moodle_url('/admin/tool/innodb/index.php', $optionsyes), get_string('yes'));
70 81
     $formcancel = new single_button(new moodle_url('/admin/'), get_string('no'), 'get');
2  admin/user/user_bulk_download.php
@@ -152,7 +152,7 @@ function user_download_csv($fields) {
152 152
     $filename = clean_filename(get_string('users').'.csv');
153 153
 
154 154
     header("Content-Type: application/download\n");
155  
-    header("Content-Disposition: attachment; filename=$filename");
  155
+    header("Content-Disposition: attachment; filename=\"$filename\"");
156 156
     header("Expires: 0");
157 157
     header("Cache-Control: must-revalidate,post-check=0,pre-check=0");
158 158
     header("Pragma: public");
252  admin/webservice/testclient_forms.php
@@ -727,3 +727,255 @@ public function get_params() {
727 727
         return $params;
728 728
     }
729 729
 }
  730
+
  731
+/**
  732
+ * Form class for create_categories() web service function test.
  733
+ *
  734
+ * @package   core_webservice
  735
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  736
+ * @copyright 2012 Fabio Souto
  737
+ */
  738
+class core_course_create_categories_form extends moodleform {
  739
+    /**
  740
+     * The form definition.
  741
+     */
  742
+    public function definition() {
  743
+        global $CFG;
  744
+
  745
+        $mform = $this->_form;
  746
+
  747
+        $mform->addElement('header', 'wstestclienthdr', get_string('testclient', 'webservice'));
  748
+
  749
+        // Note: these values are intentionally PARAM_RAW - we want users to test any rubbish as parameters.
  750
+        $data = $this->_customdata;
  751
+        if ($data['authmethod'] == 'simple') {
  752
+            $mform->addElement('text', 'wsusername', 'wsusername');
  753
+            $mform->addElement('text', 'wspassword', 'wspassword');
  754
+        } else if ($data['authmethod'] == 'token') {
  755
+            $mform->addElement('text', 'token', 'token');
  756
+        }
  757
+
  758
+        $mform->addElement('hidden', 'authmethod', $data['authmethod']);
  759
+        $mform->setType('authmethod', PARAM_SAFEDIR);
  760
+        $mform->addElement('text', 'name[0]', 'name[0]');
  761
+        $mform->addElement('text', 'parent[0]', 'parent[0]');
  762
+        $mform->addElement('text', 'idnumber[0]', 'idnumber[0]');
  763
+        $mform->addElement('text', 'description[0]', 'description[0]');
  764
+        $mform->addElement('text', 'name[1]', 'name[1]');
  765
+        $mform->addElement('text', 'parent[1]', 'parent[1]');
  766
+        $mform->addElement('text', 'idnumber[1]', 'idnumber[1]');
  767
+        $mform->addElement('text', 'description[1]', 'description[1]');
  768
+
  769
+        $mform->addElement('hidden', 'function');
  770
+        $mform->setType('function', PARAM_SAFEDIR);
  771
+
  772
+        $mform->addElement('hidden', 'protocol');
  773
+        $mform->setType('protocol', PARAM_SAFEDIR);
  774
+
  775
+        $this->add_action_buttons(true, get_string('execute', 'webservice'));
  776
+    }
  777
+
  778
+    /**
  779
+     * Get the parameters that the user submitted using the form.
  780
+     * @return array|null
  781
+     */
  782
+    public function get_params() {
  783
+        if (!$data = $this->get_data()) {
  784
+            return null;
  785
+        }
  786
+        // Remove unused from form data.
  787
+        unset($data->submitbutton);
  788
+        unset($data->protocol);
  789
+        unset($data->function);
  790
+        unset($data->wsusername);
  791
+        unset($data->wspassword);
  792
+        unset($data->token);
  793
+        unset($data->authmethod);
  794
+
  795
+        $params = array();
  796
+        $params['categories'] = array();
  797
+        for ($i=0; $i<10; $i++) {
  798
+            if (empty($data->name[$i]) or empty($data->parent[$i])) {
  799
+                continue;
  800
+            }
  801
+            $params['categories'][] = array('name'=>$data->name[$i], 'parent'=>$data->parent[$i],
  802
+                                            'idnumber'=>$data->idnumber[$i], 'description'=>$data->description[$i]);
  803
+        }
  804
+        return $params;
  805
+    }
  806
+}
  807
+
  808
+/**
  809
+ * Form class for delete_categories() web service function test.
  810
+ *
  811
+ * @package   core_webservice
  812
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  813
+ * @copyright 2012 Fabio Souto
  814
+ */
  815
+class core_course_delete_categories_form extends moodleform {
  816
+    /**
  817
+     * The form definition.
  818
+     */
  819
+    public function definition() {
  820
+        global $CFG;
  821
+
  822
+        $mform = $this->_form;
  823
+
  824
+        $mform->addElement('header', 'wstestclienthdr', get_string('testclient', 'webservice'));
  825
+
  826
+        // Note: these values are intentionally PARAM_RAW - we want users to test any rubbish as parameters.
  827
+        $data = $this->_customdata;
  828
+        if ($data['authmethod'] == 'simple') {
  829
+            $mform->addElement('text', 'wsusername', 'wsusername');
  830
+            $mform->addElement('text', 'wspassword', 'wspassword');
  831
+        } else if ($data['authmethod'] == 'token') {
  832
+            $mform->addElement('text', 'token', 'token');
  833
+        }
  834
+
  835
+        $mform->addElement('hidden', 'authmethod', $data['authmethod']);
  836
+        $mform->setType('authmethod', PARAM_SAFEDIR);
  837
+        $mform->addElement('text', 'id[0]', 'id[0]');
  838
+        $mform->addElement('text', 'newparent[0]', 'newparent[0]');
  839
+        $mform->addElement('text', 'recursive[0]', 'recursive[0]');
  840
+        $mform->addElement('text', 'id[1]', 'id[1]');
  841
+        $mform->addElement('text', 'newparent[1]', 'newparent[1]');
  842
+        $mform->addElement('text', 'recursive[1]', 'recursive[1]');
  843
+
  844
+        $mform->addElement('hidden', 'function');
  845
+        $mform->setType('function', PARAM_SAFEDIR);
  846
+
  847
+        $mform->addElement('hidden', 'protocol');
  848
+        $mform->setType('protocol', PARAM_SAFEDIR);
  849
+
  850
+        $this->add_action_buttons(true, get_string('execute', 'webservice'));
  851
+    }
  852
+
  853
+    /**
  854
+     * Get the parameters that the user submitted using the form.
  855
+     * @return array|null
  856
+     */
  857
+    public function get_params() {
  858
+        if (!$data = $this->get_data()) {
  859
+            return null;
  860
+        }
  861
+        // Remove unused from form data.
  862
+        unset($data->submitbutton);
  863
+        unset($data->protocol);
  864
+        unset($data->function);
  865
+        unset($data->wsusername);
  866
+        unset($data->wspassword);
  867
+        unset($data->token);
  868
+        unset($data->authmethod);
  869
+
  870
+        $params = array();
  871
+        $params['categories'] = array();
  872
+        for ($i=0; $i<10; $i++) {
  873
+            if (empty($data->id[$i])) {
  874
+                continue;
  875
+            }
  876
+            $attrs = array();
  877
+            $attrs['id'] = $data->id[$i];
  878
+            if (!empty($data->newparent[$i])) {
  879
+                $attrs['newparent'] = $data->newparent[$i];
  880
+            }
  881
+            if (!empty($data->recursive[$i])) {
  882
+                $attrs['recursive'] = $data->recursive[$i];
  883
+            }
  884
+            $params['categories'][] = $attrs;
  885
+        }
  886
+        return $params;
  887
+    }
  888
+}
  889
+
  890
+/**
  891
+ * Form class for create_categories() web service function test.
  892
+ *
  893
+ * @package   core_webservice
  894
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  895
+ * @copyright 2012 Fabio Souto
  896
+ */
  897
+class core_course_update_categories_form extends moodleform {
  898
+    /**
  899
+     * The form definition.
  900
+     */
  901
+    public function definition() {
  902
+        global $CFG;
  903
+
  904
+        $mform = $this->_form;
  905
+
  906
+        $mform->addElement('header', 'wstestclienthdr', get_string('testclient', 'webservice'));
  907
+
  908
+        // Note: these values are intentionally PARAM_RAW - we want users to test any rubbish as parameters.
  909
+        $data = $this->_customdata;
  910
+        if ($data['authmethod'] == 'simple') {
  911
+            $mform->addElement('text', 'wsusername', 'wsusername');
  912
+            $mform->addElement('text', 'wspassword', 'wspassword');
  913
+        } else if ($data['authmethod'] == 'token') {
  914
+            $mform->addElement('text', 'token', 'token');
  915
+        }
  916
+
  917
+        $mform->addElement('hidden', 'authmethod', $data['authmethod']);
  918
+        $mform->setType('authmethod', PARAM_SAFEDIR);
  919
+        $mform->addElement('text', 'id[0]', 'id[0]');
  920
+        $mform->addElement('text', 'name[0]', 'name[0]');
  921
+        $mform->addElement('text', 'parent[0]', 'parent[0]');
  922
+        $mform->addElement('text', 'idnumber[0]', 'idnumber[0]');
  923
+        $mform->addElement('text', 'description[0]', 'description[0]');
  924
+        $mform->addElement('text', 'id[1]', 'id[1]');
  925
+        $mform->addElement('text', 'name[1]', 'name[1]');
  926
+        $mform->addElement('text', 'parent[1]', 'parent[1]');
  927
+        $mform->addElement('text', 'idnumber[1]', 'idnumber[1]');
  928
+        $mform->addElement('text', 'description[1]', 'description[1]');
  929
+
  930
+        $mform->addElement('hidden', 'function');
  931
+        $mform->setType('function', PARAM_SAFEDIR);
  932
+
  933
+        $mform->addElement('hidden', 'protocol');
  934
+        $mform->setType('protocol', PARAM_SAFEDIR);
  935
+
  936
+        $this->add_action_buttons(true, get_string('execute', 'webservice'));
  937
+    }
  938
+
  939
+    /**
  940
+     * Get the parameters that the user submitted using the form.
  941
+     * @return array|null
  942
+     */
  943
+    public function get_params() {
  944
+        if (!$data = $this->get_data()) {
  945
+            return null;
  946
+        }
  947
+        // Remove unused from form data.
  948
+        unset($data->submitbutton);
  949
+        unset($data->protocol);
  950
+        unset($data->function);
  951
+        unset($data->wsusername);
  952
+        unset($data->wspassword);
  953
+        unset($data->token);
  954
+        unset($data->authmethod);
  955
+
  956
+        $params = array();
  957
+        $params['categories'] = array();
  958
+        for ($i=0; $i<10; $i++) {
  959
+
  960
+            if (empty($data->id[$i])) {
  961
+                continue;
  962
+            }
  963
+            $attrs = array();
  964
+            $attrs['id'] = $data->id[$i];
  965
+            if (!empty($data->name[$i])) {
  966
+                $attrs['name'] = $data->name[$i];
  967
+            }
  968
+            if (!empty($data->parent[$i])) {
  969
+                $attrs['parent'] = $data->parent[$i];
  970
+            }
  971
+            if (!empty($data->idnumber[$i])) {
  972
+                $attrs['idnumber'] = $data->idnumber[$i];
  973
+            }
  974
+            if (!empty($data->description[$i])) {
  975
+                $attrs['description'] = $data->description[$i];
  976
+            }
  977
+            $params['categories'][] = $attrs;
  978
+        }
  979
+        return $params;
  980
+    }
  981
+}
9  backup/converter/moodle1/tests/lib_test.php
@@ -35,6 +35,9 @@ class moodle1_converter_testcase extends advanced_testcase {
35 35
     /** @var string the name of the directory containing the unpacked Moodle 1.9 backup */
36 36
     protected $tempdir;
37 37
 
  38
+    /** @var string saved hash of an icon file used during testing */
  39
+    protected $iconhash;
  40
+
38 41
     protected function setUp() {
39 42
         global $CFG;
40 43
 
@@ -61,6 +64,7 @@ protected function setUp() {
61 64
             "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif",
62 65
             "$CFG->tempdir/backup/$this->tempdir/moddata/unittest/4/icon.gif"
63 66
         );
  67
+        $this->iconhash = sha1_file($CFG->tempdir.'/backup/'.$this->tempdir.'/moddata/unittest/4/icon.gif');
64 68
         copy(
65 69
             "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif",
66 70
             "$CFG->tempdir/backup/$this->tempdir/moddata/unittest/4/7/icon.gif"
@@ -272,7 +276,8 @@ public function test_migrate_file() {
272 276
         // migrate a single file
273 277
         $fileman->itemid = 4;
274 278
         $fileman->migrate_file('moddata/unittest/4/icon.gif');
275  
-        $this->assertTrue(is_file($converter->get_workdir_path().'/files/4e/4ea114b0558f53e3af8dd9afc0e0810a95c2a724'));
  279
+        $subdir = substr($this->iconhash, 0, 2);
  280
+        $this->assertTrue(is_file($converter->get_workdir_path().'/files/'.$subdir.'/'.$this->iconhash));
276 281
         // get the file id
277 282
         $fileids = $fileman->get_fileids();
278 283
         $this->assertEquals(gettype($fileids), 'array');
@@ -285,7 +290,7 @@ public function test_migrate_file() {
285 290
         $filerecordids = $converter->get_stash_itemids('files');
286 291
         foreach ($filerecordids as $filerecordid) {
287 292
             $filerecord = $converter->get_stash('files', $filerecordid);
288  
-            $this->assertEquals('4ea114b0558f53e3af8dd9afc0e0810a95c2a724', $filerecord['contenthash']);
  293
+            $this->assertEquals($this->iconhash, $filerecord['contenthash']);
289 294
             $this->assertEquals($contextid, $filerecord['contextid']);
290 295
             $this->assertEquals('mod_unittest', $filerecord['component']);
291 296
             if ($filerecord['filearea'] === 'testarea') {
15  backup/moodle2/backup_stepslib.php
@@ -364,19 +364,26 @@ protected function define_structure() {
364 364
         // Define each element separated
365 365
 
366 366
         $section = new backup_nested_element('section', array('id'), array(
367  
-            'number', 'name', 'summary', 'summaryformat', 'sequence', 'visible'));
  367
+                'number', 'name', 'summary', 'summaryformat', 'sequence', 'visible',
  368
+                'availablefrom', 'availableuntil', 'showavailability', 'groupingid'));
368 369
 
369 370
         // attach format plugin structure to $section element, only one allowed
370 371
         $this->add_plugin_structure('format', $section, false);
371 372
 
372  
-        // Define sources
  373
+        // Add nested elements for _availability table
  374
+        $avail = new backup_nested_element('availability', array('id'), array(
  375
+                'sourcecmid', 'requiredcompletion', 'gradeitemid', 'grademin', 'grademax'));
  376
+        $section->add_child($avail);
373 377
 
  378
+        // Define sources
374 379
         $section->set_source_table('course_sections', array('id' => backup::VAR_SECTIONID));
  380
+        $avail->set_source_table('course_sections_availability', array('coursesectionid' => backup::VAR_SECTIONID));
375 381
 
376 382
         // Aliases
377 383
         $section->set_source_alias('section', 'number');
378 384
 
379 385
         // Set annotations
  386
+        $section->annotate_ids('grouping', 'groupingid');
380 387
         $section->annotate_files('course', 'section', 'id');
381 388
 
382 389
         return $section;
@@ -965,7 +972,7 @@ protected function define_structure() {
965 972
         $groups = new backup_nested_element('groups');
966 973
 
967 974
         $group = new backup_nested_element('group', array('id'), array(
968  
-            'name', 'description', 'descriptionformat', 'enrolmentkey',
  975
+            'name', 'idnumber', 'description', 'descriptionformat', 'enrolmentkey',
969 976
             'picture', 'hidepicture', 'timecreated', 'timemodified'));
970 977
 
971 978
         $members = new backup_nested_element('group_members');
@@ -976,7 +983,7 @@ protected function define_structure() {
976 983
         $groupings = new backup_nested_element('groupings');
977 984
 
978 985
         $grouping = new backup_nested_element('grouping', 'id', array(
979  
-            'name', 'description', 'descriptionformat', 'configdata',
  986
+            'name', 'idnumber', 'description', 'descriptionformat', 'configdata',
980 987
             'timecreated', 'timemodified'));
981 988
 
982 989
         $groupinggroups = new backup_nested_element('grouping_groups');
9  backup/moodle2/restore_final_task.class.php
@@ -79,15 +79,16 @@ public function build() {
79 79
             $this->add_step(new restore_course_logs_structure_step('course_logs', 'course/logs.xml'));
80 80
         }
81 81
 
82  
-        // Rebuild course cache to see results, whoah!
83  
-        $this->add_step(new restore_rebuild_course_cache('rebuild_course_cache'));
84  
-
85 82
         // Review all the executed tasks having one after_restore method
86 83
         // executing it to perform some final adjustments of information
87 84
         // not available when the task was executed.
88  
-        // This step is always the last one before the one cleaning the temp stuff!
  85
+        // This step is always the last one performing modifications on restored information
  86
+        // Don't add any new step after it. Only cache rebuild and clean are allowed.
89 87
         $this->add_step(new restore_execute_after_restore('executing_after_restore'));
90 88
 
  89
+        // Rebuild course cache to see results, whoah!
  90
+        $this->add_step(new restore_rebuild_course_cache('rebuild_course_cache'));
  91
+
91 92
         // Clean the temp dir (conditionally) and drop temp table
92 93
         $this->add_step(new restore_drop_and_clean_temp_stuff('drop_and_clean_temp_stuff'));
93 94
 
93  backup/moodle2/restore_stepslib.php
@@ -716,6 +716,17 @@ public function process_group($data) {
716 716
         $data = (object)$data; // handy
717 717
         $data->courseid = $this->get_courseid();
718 718
 
  719
+        // Only allow the idnumber to be set if the user has permission and the idnumber is not already in use by
  720
+        // another a group in the same course
  721
+        $context = context_course::instance($data->courseid);
  722
+        if (isset($data->idnumber) and has_capability('moodle/course:changeidnumber', $context, $this->task->get_userid())) {
  723
+            if (groups_get_group_by_idnumber($data->courseid, $data->idnumber)) {
  724
+                unset($data->idnumber);
  725
+            }
  726
+        } else {
  727
+            unset($data->idnumber);
  728
+        }
  729
+
719 730
         $oldid = $data->id;    // need this saved for later
720 731
 
721 732
         $restorefiles = false; // Only if we end creating the group
@@ -765,6 +776,17 @@ public function process_grouping($data) {
765 776
         $data = (object)$data; // handy
766 777
         $data->courseid = $this->get_courseid();
767 778
 
  779
+        // Only allow the idnumber to be set if the user has permission and the idnumber is not already in use by
  780
+        // another a grouping in the same course
  781
+        $context = context_course::instance($data->courseid);
  782
+        if (isset($data->idnumber) and has_capability('moodle/course:changeidnumber', $context, $this->task->get_userid())) {
  783
+            if (groups_get_grouping_by_idnumber($data->courseid, $data->idnumber)) {
  784
+                unset($data->idnumber);
  785
+            }
  786
+        } else {
  787
+            unset($data->idnumber);
  788
+        }
  789
+
768 790
         $oldid = $data->id;    // need this saved for later
769 791
         $restorefiles = false; // Only if we end creating the grouping
770 792
 
@@ -992,16 +1014,24 @@ protected function define_execution() {
992 1014
 class restore_section_structure_step extends restore_structure_step {
993 1015
 
994 1016
     protected function define_structure() {
  1017
+        global $CFG;
  1018
+
  1019
+        $paths = array();
  1020
+
995 1021
         $section = new restore_path_element('section', '/section');
  1022
+        $paths[] = $section;
  1023
+        if ($CFG->enableavailability) {
  1024
+            $paths[] = new restore_path_element('availability', '/section/availability');
  1025
+        }
996 1026
 
997 1027
         // Apply for 'format' plugins optional paths at section level
998 1028
         $this->add_plugin_structure('format', $section);
999 1029
 
1000  
-        return array($section);
  1030
+        return $paths;
1001 1031
     }
1002 1032
 
1003 1033
     public function process_section($data) {
1004  
-        global $DB;
  1034
+        global $CFG, $DB;
1005 1035
         $data = (object)$data;
1006 1036
         $oldid = $data->id; // We'll need this later
1007 1037
 
@@ -1018,6 +1048,18 @@ public function process_section($data) {
1018 1048
             $section->summaryformat = $data->summaryformat;
1019 1049
             $section->sequence = '';
1020 1050
             $section->visible = $data->visible;
  1051
+            if (empty($CFG->enableavailability)) { // Process availability information only if enabled.
  1052
+                $section->availablefrom = 0;
  1053
+                $section->availableuntil = 0;
  1054
+                $section->showavailability = 0;
  1055
+            } else {
  1056
+                $section->availablefrom = isset($data->availablefrom) ? $this->apply_date_offset($data->availablefrom) : 0;
  1057
+                $section->availableuntil = isset($data->availableuntil) ? $this->apply_date_offset($data->availableuntil) : 0;
  1058
+                $section->showavailability = isset($data->showavailability) ? $data->showavailability : 0;
  1059
+            }
  1060
+            if (!empty($CFG->enablegroupmembersonly)) { // Only if enablegroupmembersonly is enabled
  1061
+                $section->groupingid = isset($data->groupingid) ? $this->get_mappingid('grouping', $data->groupingid) : 0;
  1062
+            }
1021 1063
             $newitemid = $DB->insert_record('course_sections', $section);
1022 1064
             $restorefiles = true;
1023 1065
 
@@ -1032,6 +1074,16 @@ public function process_section($data) {
1032 1074
                 $section->summaryformat = $data->summaryformat;
1033 1075
                 $restorefiles = true;
1034 1076
             }
  1077
+            if (empty($secrec->groupingid)) {
  1078
+                if (!empty($CFG->enablegroupmembersonly)) { // Only if enablegroupmembersonly is enabled
  1079
+                    $section->groupingid = isset($data->groupingid) ? $this->get_mappingid('grouping', $data->groupingid) : 0;
  1080
+                }
  1081
+            }
  1082
+
  1083
+            // Don't update available from, available until, or show availability
  1084
+            // (I didn't see a useful way to define whether existing or new one should
  1085
+            // take precedence).
  1086
+
1035 1087
             $DB->update_record('course_sections', $section);
1036 1088
             $newitemid = $secrec->id;
1037 1089
         }
@@ -1055,10 +1107,47 @@ public function process_section($data) {
1055 1107
         //}
1056 1108
     }
1057 1109
 
  1110
+    public function process_availability($data) {
  1111
+        global $DB;
  1112
+        $data = (object)$data;
  1113
+        $data->coursesectionid = $this->task->get_sectionid();
  1114
+        // NOTE: Other values in $data need updating, but these (cm,
  1115
+        // grade items) have not yet been restored.
  1116
+        $DB->insert_record('course_sections_availability', $data);
  1117
+    }
  1118
+
1058 1119
     protected function after_execute() {
1059 1120
         // Add section related files, with 'course_section' itemid to match
1060 1121
         $this->add_related_files('course', 'section', 'course_section');
1061 1122
     }
  1123
+
  1124
+    public function after_restore() {
  1125
+        global $DB;
  1126
+
  1127
+        $sectionid = $this->get_task()->get_sectionid();
  1128
+
  1129
+        // Get data object for current section availability (if any)
  1130
+        // TODO: This can be processing already existing records, we need to be able to know which ones
  1131
+        //       are the just restored ones, perhaps creating 'course_sections_availability' mappings for them.
  1132
+        // TODO: Also, this must avoid duplicates, so if one course module or one grade item already is being
  1133
+        //       used for some availability rule... we need to handle that carefully.
  1134
+        $data = $DB->get_record('course_sections_availability',
  1135
+                array('coursesectionid' => $sectionid), 'id, sourcecmid, gradeitemid', IGNORE_MISSING);
  1136
+
  1137
+        // Update mappings
  1138
+        if ($data) {
  1139
+            $data->sourcecmid = $this->get_mappingid('course_module', $data->sourcecmid);
  1140
+            if (!$data->sourcecmid) {
  1141
+                $data->sourcecmid = null;
  1142
+            }
  1143
+            $data->gradeitemid = $this->get_mappingid('grade_item', $data->gradeitemid);
  1144
+            if (!$data->gradeitemid) {
  1145
+                $data->gradeitemid = null;
  1146
+            }
  1147
+
  1148
+            $DB->update_record('course_sections_availability', $data);
  1149
+        }
  1150
+    }
1062 1151
 }
1063 1152
 
1064 1153
 
12  backup/util/plan/restore_structure_step.class.php
@@ -395,6 +395,8 @@ public function launch_after_restore_methods() {
395 395
                 $pobject->launch_after_restore_methods();
396 396
             }
397 397
         }
  398
+        // Finally execute own (restore_structure_step) after_restore method
  399
+        $this->after_restore();
398 400
     }
399 401
 
400 402
     /**
@@ -409,6 +411,16 @@ protected function after_execute() {
409 411
     }
410 412
 
411 413
     /**
  414
+     * This method will be executed after the rest of the restore has been processed.
  415
+     *
  416
+     * Use if you need to update IDs based on things which are restored after this
  417
+     * step has completed.
  418
+     */
  419
+    protected function after_restore() {
  420
+        // do nothing by default
  421
+    }
  422
+
  423
+    /**
412 424
      * Prepare the pathelements for processing, looking for duplicates, applying
413 425
      * processing objects and other adjustments
414 426
      */
33  calendar/lib.php
@@ -1050,28 +1050,6 @@ function calendar_get_link_href($linkbase, $d, $m, $y) {
1050 1050
 }
1051 1051
 
1052 1052
 /**
1053  
- * This function has been deprecated as of Moodle 2.0... DO NOT USE!!!!!
1054  
- *
1055  
- * @deprecated Moodle 2.0 - MDL-24284 please do not use this function any more.
1056  
- * @todo MDL-31134 - will be removed in Moodle 2.3
1057  
- * @see calendar_get_link_href()
1058  
- *
1059  
- * @param string $text
1060  
- * @param string|moodle_url $linkbase
1061  
- * @param int|null $d The number of the day.
1062  
- * @param int|null $m The number of the month.
1063  
- * @param int|null $y The number of the year.
1064  
- * @return string HTML link
1065  
- */
1066  
-function calendar_get_link_tag($text, $linkbase, $d, $m, $y) {
1067  
-    $url = calendar_get_link_href(new moodle_url($linkbase), $d, $m, $y);
1068  
-    if (empty($url)) {
1069  
-        return $text;
1070  
-    }
1071  
-    return html_writer::link($url, $text);
1072  
-}
1073  
-
1074  
-/**
1075 1053
  * Build and return a previous month HTML link, with an arrow.
1076 1054
  *
1077 1055
  * @param string $text The text label.
@@ -1491,15 +1469,16 @@ function calendar_get_default_courses() {
1491 1469
     }
1492 1470
 
1493 1471
     $courses = array();
1494  
-    if (!empty($CFG->calendar_adminseesall) && has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_SYSTEM))) {
  1472
+    if (!empty($CFG->calendar_adminseesall) && has_capability('moodle/calendar:manageentries', context_system::instance())) {
1495 1473
         list ($select, $join) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
1496  
-        $sql = "SELECT DISTINCT c.* $select
  1474
+        $sql = "SELECT c.* $select
1497 1475
                   FROM {course} c
1498  
-                  JOIN {event} e ON e.courseid = c.id
1499  
-                  $join";
  1476
+                  $join
  1477
+                  WHERE EXISTS (SELECT 1 FROM {event} e WHERE e.courseid = c.id)
  1478
+                  ";
1500 1479
         $courses = $DB->get_records_sql($sql, null, 0, 20);
1501 1480
         foreach ($courses as $course) {
1502  
-            context_instance_preload($course);
  1481
+            context_helper::preload_from_record($course);
1503 1482
         }
1504 1483
         return $courses;
1505 1484
     }
7  config-dist.php
@@ -38,7 +38,7 @@
38 38
 // will be stored.  This database must already have been created         //
39 39
 // and a username/password created to access it.                         //
40 40
 
41  
-$CFG->dbtype    = 'pgsql';      // 'pgsql', 'mysqli', 'mssql' or 'oci'
  41
+$CFG->dbtype    = 'pgsql';      // 'pgsql', 'mysqli', 'mssql', 'sqlsrv' or 'oci'
42 42
 $CFG->dblibrary = 'native';     // 'native' only at the moment
43 43
 $CFG->dbhost    = 'localhost';  // eg 'localhost' or 'db.isp.com' or IP
44 44
 $CFG->dbname    = 'moodle';     // database name, eg moodle
@@ -431,6 +431,11 @@
431 431
 //
432 432
 //      $CFG->cssoptimiserpretty = true;
433 433
 //
  434
+// Use the following flag to completely disable the Available update notifications
  435
+// feature and hide it from the server administration UI.
  436
+//
  437
+//      $CFG->disableupdatenotifications = true;
  438
+//
434 439
 //=========================================================================
435 440
 // 8. SETTINGS FOR DEVELOPMENT SERVERS - not intended for production use!!!
436 441
 //=========================================================================
888  course/dndupload.js
... ...
@@ -0,0 +1,888 @@
  1
+// This file is part of Moodle - http://moodle.org/
  2
+//
  3
+// Moodle is free software: you can redistribute it and/or modify
  4
+// it under the terms of the GNU General Public License as published by
  5
+// the Free Software Foundation, either version 3 of the License, or
  6
+// (at your option) any later version.
  7
+//
  8
+// Moodle is distributed in the hope that it will be useful,
  9
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
  10
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11
+// GNU General Public License for more details.
  12
+//
  13
+// You should have received a copy of the GNU General Public License
  14
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  15
+
  16
+/**
  17
+ * Javascript library for enableing a drag and drop upload to courses
  18
+ *
  19
+ * @package    core
  20
+ * @subpackage course
  21
+ * @copyright  2012 Davo Smith
  22
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23
+ */
  24
+M.course_dndupload = {
  25
+    // YUI object.
  26
+    Y: null,
  27
+    // URL for upload requests
  28
+    url: M.cfg.wwwroot + '/course/dndupload.php',
  29
+    // maximum size of files allowed in this form
  30
+    maxbytes: 0,
  31
+    // ID of the course we are on
  32
+    courseid: null,
  33
+    // Data about the different file/data handlers that are available
  34
+    handlers: null,
  35
+    // Nasty hack to distinguish between dragenter(first entry),
  36
+    // dragenter+dragleave(moving between child elements) and dragleave (leaving element)
  37
+    entercount: 0,
  38
+    // Used to keep track of the section we are dragging across - to make
  39
+    // spotting movement between sections more reliable
  40
+    currentsection: null,
  41
+    // Used to store the pending uploads whilst the user is being asked for further input
  42
+    uploadqueue: null,
  43
+    // True if the there is currently a dialog being shown (asking for a name, or giving a
  44
+    // choice of file handlers)
  45
+    uploaddialog: false,
  46
+    // An array containing the last selected file handler for each file type
  47
+    lastselected: null,
  48
+
  49
+    // The following are used to identify specific parts of the course page
  50
+
  51
+    // The type of HTML element that is a course section
  52
+    sectiontypename: 'li',
  53
+    // The classes that an element must have to be identified as a course section
  54
+    sectionclasses: ['section', 'main'],
  55
+    // The ID of the main content area of the page (for adding the 'status' div)
  56
+    pagecontentid: 'page-content',
  57
+    // The selector identifying the list of modules within a section (note changing this may require
  58
+    // changes to the get_mods_element function)
  59
+    modslistselector: 'ul.section',
  60
+
  61
+    /**
  62
+     * Initalise the drag and drop upload interface
  63
+     * Note: one and only one of options.filemanager and options.formcallback must be defined
  64
+     *
  65
+     * @param Y the YUI object
  66
+     * @param object options {
  67
+     *            courseid: ID of the course we are on
  68
+     *            maxbytes: maximum size of files allowed in this form
  69
+     *            handlers: Data about the different file/data handlers that are available
  70
+     *          }
  71
+     */
  72
+    init: function(Y, options) {
  73
+        this.Y = Y;
  74
+
  75
+        if (!this.browser_supported()) {
  76
+            return; // Browser does not support the required functionality
  77
+        }
  78
+
  79
+        this.maxbytes = options.maxbytes;
  80
+        this.courseid = options.courseid;
  81
+        this.handlers = options.handlers;
  82
+        this.uploadqueue = new Array();
  83
+        this.lastselected = new Array();
  84
+
  85
+        var sectionselector = this.sectiontypename + '.' + this.sectionclasses.join('.');
  86
+        var sections = this.Y.all(sectionselector);
  87
+        if (sections.isEmpty()) {
  88
+            return; // No sections - incompatible course format or front page.
  89
+        }
  90
+        sections.each( function(el) {
  91
+            this.add_preview_element(el);
  92
+            this.init_events(el);
  93
+        }, this);
  94
+
  95
+        var div = this.add_status_div();
  96
+        div.setContent(M.util.get_string('dndworking', 'moodle'));
  97
+    },
  98
+
  99
+    /**
  100
+     * Add a div element to tell the user that drag and drop upload
  101
+     * is available (or to explain why it is not available)
  102
+     * @return the DOM element to add messages to