Permalink
Browse files

Merge branch 'MOODLE_26_STABLE' into install_26_STABLE

  • Loading branch information...
AMOS bot
AMOS bot committed Jun 13, 2014
2 parents 0d893ad + 89c7782 commit eb4b4c7ba094668f43b2e8fc86900e873465d53a
Showing with 775 additions and 165 deletions.
  1. +1 −1 admin/renderer.php
  2. +6 −8 backup/moodle2/backup_stepslib.php
  3. +86 −50 backup/moodle2/restore_stepslib.php
  4. +21 −1 backup/util/dbops/backup_structure_dbops.class.php
  5. +1 −1 backup/util/structure/backup_structure_processor.class.php
  6. +190 −0 blocks/navigation/tests/behat/expand_courses_node.feature
  7. +0 −2 blocks/navigation/tests/behat/view_my_courses.feature
  8. +3 −3 enrol/self/tests/behat/self_enrolment.feature
  9. +20 −3 group/group_form.php
  10. +39 −0 group/tests/behat/create_groups.feature
  11. +51 −0 group/tests/behat/update_groups.feature
  12. +1 −0 lang/en/cache.php
  13. +1 −1 lang/en/error.php
  14. +1 −0 lang/en/group.php
  15. +6 −1 lib/classes/useragent.php
  16. +10 −0 lib/db/caches.php
  17. +7 −0 lib/db/upgrade.php
  18. +21 −1 lib/db/upgradelib.php
  19. +2 −2 lib/filelib.php
  20. +8 −1 lib/filestorage/stored_file.php
  21. +4 −3 lib/filestorage/tests/file_storage_test.php
  22. +70 −1 lib/navigationlib.php
  23. +0 −3 lib/questionlib.php
  24. +27 −0 lib/tests/theme_config_test.php
  25. +3 −1 mod/data/locallib.php
  26. +17 −9 mod/lti/return.php
  27. +8 −2 mod/quiz/editlib.php
  28. +13 −0 mod/quiz/lib.php
  29. +2 −1 mod/scorm/locallib.php
  30. +10 −17 mod/scorm/module.js
  31. BIN pix/f/publisher-128.png
  32. BIN pix/f/publisher-24.png
  33. BIN pix/f/publisher-256.png
  34. BIN pix/f/publisher-32.png
  35. BIN pix/f/publisher-48.png
  36. BIN pix/f/publisher-64.png
  37. BIN pix/f/publisher-72.png
  38. BIN pix/f/publisher-80.png
  39. BIN pix/f/publisher-96.png
  40. BIN pix/f/publisher.png
  41. +4 −1 question/type/questiontypebase.php
  42. +46 −0 question/type/random/backup/moodle2/restore_qtype_random_plugin.class.php
  43. +65 −0 question/type/random/db/upgrade.php
  44. +7 −1 question/type/random/questiontype.php
  45. +1 −1 question/type/random/version.php
  46. +3 −1 report/log/index.php
  47. +3 −2 theme/base/style/core.css
  48. +14 −44 theme/bootstrapbase/less/moodle/core.less
  49. +1 −1 theme/bootstrapbase/style/moodle.css
  50. +2 −2 version.php
View
@@ -1369,7 +1369,7 @@ public function environment_check_table($result, $environment_results) {
get_string('report'),
get_string('status'),
);
- $servertable->colclasses = array('centeralign name', 'centeralign status', 'leftalign report', 'centeralign info');
+ $servertable->colclasses = array('centeralign name', 'centeralign info', 'leftalign report', 'centeralign status');
$servertable->attributes['class'] = 'admintable environmenttable generaltable';
$servertable->id = 'serverstatus';
@@ -28,8 +28,7 @@
defined('MOODLE_INTERNAL') || die();
/**
- * create the temp dir where backup/restore will happen,
- * delete old directories and create temp ids table
+ * Create the temp dir where backup/restore will happen and create temp ids table.
*/
class create_and_clean_temp_stuff extends backup_execution_step {
@@ -38,19 +37,18 @@ protected function define_execution() {
$progress->start_progress('Deleting backup directories');
backup_helper::check_and_create_backup_dir($this->get_backupid());// Create backup temp dir
backup_helper::clear_backup_dir($this->get_backupid(), $progress); // Empty temp dir, just in case
- backup_helper::delete_old_backup_dirs(time() - (4 * 60 * 60), $progress); // Delete > 4 hours temp dirs
backup_controller_dbops::drop_backup_ids_temp_table($this->get_backupid()); // Drop ids temp table
backup_controller_dbops::create_backup_ids_temp_table($this->get_backupid()); // Create ids temp table
$progress->end_progress();
}
}
/**
- * delete the temp dir used by backup/restore (conditionally),
- * delete old directories and drop tem ids table. Note we delete
+ * Delete the temp dir used by backup/restore (conditionally),
+ * delete old directories and drop temp ids table. Note we delete
* the directory but not the corresponding log file that will be
- * there for, at least, 4 hours - only delete_old_backup_dirs()
- * deletes log files (for easier access to them)
+ * there for, at least, 1 week - only delete_old_backup_dirs() or cron
+ * deletes log files (for easier access to them).
*/
class drop_and_clean_temp_stuff extends backup_execution_step {
@@ -60,7 +58,7 @@ protected function define_execution() {
global $CFG;
backup_controller_dbops::drop_backup_ids_temp_table($this->get_backupid()); // Drop ids temp table
- backup_helper::delete_old_backup_dirs(time() - (4 * 60 * 60)); // Delete > 4 hours temp dirs
+ backup_helper::delete_old_backup_dirs(strtotime('-1 week')); // Delete > 1 week old temp dirs.
// Delete temp dir conditionally:
// 1) If $CFG->keeptempdirectoriesonbackup is not enabled
// 2) If backup temp dir deletion has been marked to be avoided
@@ -67,7 +67,7 @@ protected function define_execution() {
restore_controller_dbops::drop_restore_temp_tables($this->get_restoreid()); // Drop ids temp table
$progress = $this->task->get_progress();
$progress->start_progress('Deleting backup dir');
- backup_helper::delete_old_backup_dirs(time() - (4 * 60 * 60), $progress); // Delete > 4 hours temp dirs
+ backup_helper::delete_old_backup_dirs(strtotime('-1 week'), $progress); // Delete > 1 week old temp dirs.
if (empty($CFG->keeptempdirectoriesonbackup)) { // Conditionally
backup_helper::delete_backup_dir($this->task->get_tempdir(), $progress); // Empty restore dir
}
@@ -3558,74 +3558,110 @@ protected function define_execution() {
* Execution step that will create all the question/answers/qtype-specific files for the restored
* questions. It must be executed after {@link restore_move_module_questions_categories}
* because only then each question is in its final category and only then the
- * context can be determined
- *
- * TODO: Improve this. Instead of looping over each question, it can be reduced to
- * be done by contexts (this will save a huge ammount of queries)
+ * contexts can be determined.
*/
class restore_create_question_files extends restore_execution_step {
+ /** @var array Question-type specific component items cache. */
+ private $qtypecomponentscache = array();
+
+ /**
+ * Preform the restore_create_question_files step.
+ */
protected function define_execution() {
global $DB;
// Track progress, as this task can take a long time.
$progress = $this->task->get_progress();
$progress->start_progress($this->get_name(), core_backup_progress::INDETERMINATE);
- // Let's process only created questions
- $questionsrs = $DB->get_recordset_sql("SELECT bi.itemid, bi.newitemid, bi.parentitemid, q.qtype
+ // Parentitemids of question_createds in backup_ids_temp are the category it is in.
+ // MUST use a recordset, as there is no unique key in the first (or any) column.
+ $catqtypes = $DB->get_recordset_sql("SELECT DISTINCT bi.parentitemid AS categoryid, q.qtype as qtype
FROM {backup_ids_temp} bi
JOIN {question} q ON q.id = bi.newitemid
WHERE bi.backupid = ?
- AND bi.itemname = 'question_created'", array($this->get_restoreid()));
- foreach ($questionsrs as $question) {
- // Report progress for each question.
- $progress->progress();
-
- // Get question_category mapping, it contains the target context for the question
- if (!$qcatmapping = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'question_category', $question->parentitemid)) {
- // Something went really wrong, cannot find the question_category for the question
- debugging('Error fetching target context for question', DEBUG_DEVELOPER);
- continue;
- }
- // Calculate source and target contexts
- $oldctxid = $qcatmapping->info->contextid;
- $newctxid = $qcatmapping->parentitemid;
-
- // Add common question files (question and question_answer ones)
- restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'questiontext',
- $oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true, $progress);
- restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'generalfeedback',
- $oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true, $progress);
- restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'answer',
- $oldctxid, $this->task->get_userid(), 'question_answer', null, $newctxid, true, $progress);
- restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'answerfeedback',
- $oldctxid, $this->task->get_userid(), 'question_answer', null, $newctxid, true, $progress);
- restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'hint',
- $oldctxid, $this->task->get_userid(), 'question_hint', null, $newctxid, true, $progress);
- restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'correctfeedback',
- $oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true, $progress);
- restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'partiallycorrectfeedback',
- $oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true, $progress);
- restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'incorrectfeedback',
- $oldctxid, $this->task->get_userid(), 'question_created', $question->itemid, $newctxid, true, $progress);
-
- // Add qtype dependent files
- $components = backup_qtype_plugin::get_components_and_fileareas($question->qtype);
- foreach ($components as $component => $fileareas) {
- foreach ($fileareas as $filearea => $mapping) {
- // Use itemid only if mapping is question_created
- $itemid = ($mapping == 'question_created') ? $question->itemid : null;
- restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), $component, $filearea,
- $oldctxid, $this->task->get_userid(), $mapping, $itemid, $newctxid, true, $progress);
+ AND bi.itemname = 'question_created'
+ ORDER BY categoryid ASC", array($this->get_restoreid()));
+
+ $currentcatid = -1;
+ foreach ($catqtypes as $categoryid => $row) {
+ $qtype = $row->qtype;
+
+ // Check if we are in a new category.
+ if ($currentcatid !== $categoryid) {
+ // Report progress for each category.
+ $progress->progress();
+
+ if (!$qcatmapping = restore_dbops::get_backup_ids_record($this->get_restoreid(),
+ 'question_category', $categoryid)) {
+ // Something went really wrong, cannot find the question_category for the question_created records.
+ debugging('Error fetching target context for question', DEBUG_DEVELOPER);
+ continue;
}
+
+ // Calculate source and target contexts.
+ $oldctxid = $qcatmapping->info->contextid;
+ $newctxid = $qcatmapping->parentitemid;
+
+ $this->send_common_files($oldctxid, $newctxid, $progress);
+ $currentcatid = $categoryid;
}
+
+ $this->send_qtype_files($qtype, $oldctxid, $newctxid, $progress);
}
- $questionsrs->close();
+ $catqtypes->close();
$progress->end_progress();
}
-}
+ /**
+ * Send the common question files to a new context.
+ *
+ * @param int $oldctxid Old context id.
+ * @param int $newctxid New context id.
+ * @param \core\progress $progress Progress object to use.
+ */
+ private function send_common_files($oldctxid, $newctxid, $progress) {
+ // Add common question files (question and question_answer ones).
+ restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'questiontext',
+ $oldctxid, $this->task->get_userid(), 'question_created', null, $newctxid, true, $progress);
+ restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'generalfeedback',
+ $oldctxid, $this->task->get_userid(), 'question_created', null, $newctxid, true, $progress);
+ restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'answer',
+ $oldctxid, $this->task->get_userid(), 'question_answer', null, $newctxid, true, $progress);
+ restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'answerfeedback',
+ $oldctxid, $this->task->get_userid(), 'question_answer', null, $newctxid, true, $progress);
+ restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'hint',
+ $oldctxid, $this->task->get_userid(), 'question_hint', null, $newctxid, true, $progress);
+ restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'correctfeedback',
+ $oldctxid, $this->task->get_userid(), 'question_created', null, $newctxid, true, $progress);
+ restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'partiallycorrectfeedback',
+ $oldctxid, $this->task->get_userid(), 'question_created', null, $newctxid, true, $progress);
+ restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), 'question', 'incorrectfeedback',
+ $oldctxid, $this->task->get_userid(), 'question_created', null, $newctxid, true, $progress);
+ }
+
+ /**
+ * Send the question type specific files to a new context.
+ *
+ * @param text $qtype The qtype name to send.
+ * @param int $oldctxid Old context id.
+ * @param int $newctxid New context id.
+ * @param \core\progress $progress Progress object to use.
+ */
+ private function send_qtype_files($qtype, $oldctxid, $newctxid, $progress) {
+ if (!isset($this->qtypecomponentscache[$qtype])) {
+ $this->qtypecomponentscache[$qtype] = backup_qtype_plugin::get_components_and_fileareas($qtype);
+ }
+ $components = $this->qtypecomponentscache[$qtype];
+ foreach ($components as $component => $fileareas) {
+ foreach ($fileareas as $filearea => $mapping) {
+ restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), $component, $filearea,
+ $oldctxid, $this->task->get_userid(), $mapping, null, $newctxid, true, $progress);
+ }
+ }
+ }
+}
/**
* Try to restore aliases and references to external files.
@@ -103,7 +103,18 @@ public static function insert_backup_ids_record($backupid, $itemname, $itemid) {
}
}
- public static function annotate_files($backupid, $contextid, $component, $filearea, $itemid) {
+ /**
+ * Adds backup id database record for all files in the given file area.
+ *
+ * @param string $backupid Backup ID
+ * @param int $contextid Context id
+ * @param string $component Component
+ * @param string $filearea File area
+ * @param int $itemid Item id
+ * @param core_backup_progress $progress
+ */
+ public static function annotate_files($backupid, $contextid, $component, $filearea, $itemid,
+ core_backup_progress $progress = null) {
global $DB;
$sql = 'SELECT id
FROM {files}
@@ -120,10 +131,19 @@ public static function annotate_files($backupid, $contextid, $component, $filear
$sql .= ' AND itemid = ?';
$params[] = $itemid;
}
+ if ($progress) {
+ $progress->start_progress('');
+ }
$rs = $DB->get_recordset_sql($sql, $params);
foreach ($rs as $record) {
+ if ($progress) {
+ $progress->progress();
+ }
self::insert_backup_ids_record($backupid, 'file', $record->id);
}
+ if ($progress) {
+ $progress->end_progress();
+ }
$rs->close();
}
@@ -86,7 +86,7 @@ public function process_nested_element(base_nested_element $nested) {
foreach ($area as $filearea => $info) {
$contextid = !is_null($info->contextid) ? $info->contextid : $this->get_var(backup::VAR_CONTEXTID);
$itemid = !is_null($info->element) ? $info->element->get_value() : null;
- backup_structure_dbops::annotate_files($backupid, $contextid, $component, $filearea, $itemid);
+ backup_structure_dbops::annotate_files($backupid, $contextid, $component, $filearea, $itemid, $this->progress);
}
}
}
Oops, something went wrong.

0 comments on commit eb4b4c7

Please sign in to comment.